Webhooks/Service Accounts/Pipeline Permissions in Spinnaker

A common question that we encounter here at Armory: how do I enable tools like Jenkins or Artifactory to call Spinnaker and trigger a pipeline.  How do I setup the authentication/authorization to allow this to happen?  The answer is pretty straightforward, though the terminology used is not what most operations staff would utilize.  Today we’ll discuss one aspect of this process - setting up the webhooks (aka Triggers).  Let’s dive into some of the common Spinnaker terms before we talk about solutions.

Service Accounts

Service accounts in Spinnaker are merely abstractions around a set of role permissions.  These are used to have pipelines execute with a certain set of permissions. They are not real users, cannot be logged in, don’t query any auth mechanism, and are not your traditional AD service account.  They’re created through API calls to Front50 and are then only used to set the permissions a pipeline executes with.

Pipeline Permissions

This is an alpha level feature that allows a service account to be automatically created for a given pipeline.  All you have to do when creating the pipeline is specify which roles the pipeline should execute with.  Then the pipeline will be able to access accounts that the role can access utilizing the created pipeline permission.  Long term, this feature has the potential to replace service accounts, and you can migrate to pipeline permissions from service accounts.  But it's essentially service accounts under the hood.

RBAC

Role-Based Access Controls.  RBAC in Spinnaker is set at either account or application levels, with read or write permissions for accounts and read, write and execute permissions for "applications." Permissions can be applied to "Roles."  A role in Spinnaker is an AD Group, a SAML assertion group, Google Group, or similar system.  Permissions are never assigned directly to a user or service account but to roles.  More details on Spinnaker RBAC can be found in the Spinnaker security setup instructions.

Putting it All Together...

Knowing the above, let’s look at how service accounts, pipeline permissions, and RBAC interact and allow Spinnaker to deliver product.  This too is pretty straight forward though often a cause for confusion.  The first thing to realize - most webhooks in Spinnaker do not utilize authentication via an API token, bearer token, or similar mechanism.  Instead, Spinnaker validates the contents of a webhook payload (think shared secret).  Certain types of “webhooks” automatically require such a payload.  GitHub webhooks, for example, require a “Secret” field.  But standard webhooks require you to validate the contents using “Payload Constraints”.  There are a few other types of triggers (aka Jenkins, Pub/Sub) but most use content validation vs. authentication tokens.  Jenkins is one of the few that’s a pull vs. a push method.  This means that Spinnaker communicates with Jenkins vs. Jenkins pushing to Spinnaker.  Webhooks which are sent to Spinnaker is the preferred method, as it is less load on your infrastructure.  Please note that different webhooks support slightly different UI but all of these should operate similarly for your pipeline.  For a full list including more details of each see the triggering pipelines guides on spinnaker.io.

Let's see this in action.  For the purposes of this demo, I'll be using the wonderful Minnaker project running on VMWare Fusion locally with an Ubuntu 18 LTS image.

  1. Do a basic install of Ubuntu 18
  2. Install Minnaker
  3. Get the username and password from your server
  4. Log into the UI and click on the "spin" application which is auto created for you.
  5. Select "Pipelines”
  6. Create a pipeline called "Test". In this pipeline, you can add an "Automated Trigger"

Please note the source URL.  I added a simple "Wait for manual judgement" stage as an example.  Next, you should be able to curl the webhook and see your pipeline execute.  You'll want to curl your GATE (aka API) end point, not the UI endpoint.

curl --insecure -H "Content-Type: application/json" -X POST https://REPLACEME_WITH_IP/api/v1/webhooks/webhook/TestApplication  -d '{"SuperSecret":"SecretValue"}'

To test that this only executes with a given payload, you can remove the secret or change its value.  Though not the same thing as setting up authentication for access this one of the standard methods to secure webhook execution against arbitrary runs.

Finally…

So your standard workflow on these systems.  Jenkins or your CI system creates an artifact.  This triggers one or more pipelines to execute.  These pipelines will execute with a service account or pipeline permission acting as the “role” that was assigned to the pipeline (negating the need to set up custom users).  Though there are definite possible improvements to the overall security of this setup (e.g. “only a webhook from this IP is allowed”), this is a relatively simple solution that works really well.  This pattern is very common in any CI/CD system, and Spinnaker, as the pinnacle of CD systems, interacts with this beautifully.  Please let us know if you’d like to see some of these examples!

Other reads

Now that you know how to trigger pipelines it’s worth a discussion of “Artifacts” - simply executing a pipeline doesn’t tell you how to get the files the webhook says are ready to be deployed!  Here’s some good follow ups on this topic:

Next Steps…

We’ll be working on a follow up blog post regarding Authorization (AuthZ in Spinnaker terms) along with examples, creating service accounts and how they affect tasks.  Please stay tuned!

Have questions or want to learn more? Please don’t hesitate to reach out to us here or on Spinnaker Slack - we’d love to chat!