Spinnaker Authorization setup using GSuite
Purpose
This document is a how-to-do guide to setup the authorization in Spinnaker applications and pipelines. Moreover, this is an extension of the Spinnaker SAML Authentication using GSuite SAML document to help in configuring the roles for authorization.
We will discuss about passing GSuite roles to Spinnaker in two methods:
- Passing GSuite Custom attributes as implicite roles in Authentication,
- Passing GSuite Groups as roles in explicit Authorization.
Scope
We have configured and tested Authorization in Spinnaker 1.16.2, but should work on any version since 1.11.x.
Pre-Requirements
Before configuring Spinnaker, ensure that the following items are working/configured…
Spinnaker enabled with SAML authentication using GSuite You should be an Administrator on GSuite to configure SAML app
For passing GSuite groups explicitly in Spinnaker authorization, you need a Service account in GCP.
Passing GSuite Custom Attributes as Implicit roles in Authentication
Why need Custom attribute?
While most of the SAML IdP (Identity Provider) has the option of passing the group membership to Service Provider (SP – i.e. the application implmenting SAML) via the in-built attribute called ‘memberOf’, GSuite does not have this attribute exposed in SAML apps. As of writing this document, we could find the following in-built attributes only as passable to SP apps.
- Basic Information: First Name, Last Name, Primary Email
- Contact Information: Phone Number, Address
- Employee Details: Job Title, Department, Cost Center
Should we need any additional information to be passed to SP app, we can leverage GSuite User’s Custom attributes.
GSuite Custom attribute as Roles
The procedure to use Custom attribute in Spinnaker authorization is,
On GSuite,
- Create a Custom attribute for users
- Associate Users’ with Custom attribute values (aka Roles)
- In GSuite SAML apps, configure Attribute Mappings
On Spinnaker Halyard,
- Map the GSuite Custom attribute to Halyard attribute ‘roles’
- Configure Authorization as ‘EXTERNAL’type
- Enable authorization
Procedure in GSuite
- Login to GSuite as an Administrator (admin.google.com).
a. Navigate to Users > Click ‘More’ > Manage Custom Attributes. You will be taken to ‘Manage user attributes’ page. Click ‘ADD CUSTOM ATTRIBUTE’
b. Fill in the fields – Category, Description and Custom fields as shown in the picture. Note – the Custom field is a multi-value text field. - Now you can set Custom attribute’s value for every user. To do so, Go to every user’s page > Click ‘User Information’. Locate the new category ‘Spinnaker’ and set multiple values as required. Every value should be on a separate line.
- Now you can configure your SAML Attribute mapping. Go to Apps (from the main menu) > SAML Apps > Spinndd (our App) > Click ‘Attribute Mapping’. Do the attribute mapping as in the picture. Remember the word on the lefttext field is to be used in Halyard configuration.
Procedure in Spinnaker Halyard
- Map the GSuite Custom attribute to Halyard attribute ‘roles‘
hal config security authn saml edit \ --user-attribute-mapping-roles spinnakerRoles \ --user-attribute-mapping-roles-delimiter ,
- Configure Authorization as ‘EXTERNAL’ type
hal config security authz edit --type EXTERNAL
- Enable authorization
hal config security authz enable
Now apply the changes with hal deploy apply command and check Spinnaker authentication.
Once Spinnaker has applied the changes, login to Spinnaker and then check the URL – https://spin dd.opsmx.com:30084/auth/user
JSON output shows that roles are set with Custom attribute values from GSuite under ‘roles’ element.
{ "email": "sagayaraj.d@opsmx.io", "username": "sagayaraj.d@opsmx.io", "firstName": "Sagayaraj", "lastName": "David", "roles": [ "engineering", "test" ], "allowedAccounts": [ "k8s-qa-spin", "saga-azure-account" ], "enabled": true, "authorities": [ { "authority": "engineering" }, { "authority": "test" } ], "accountNonExpired": true, "credentialsNonExpired": true, "accountNonLocked": true }
At this point, if you create a new application or edit an application in Spinnaker, you should see that ‘Permissions’ field is visible with drop-down values being populated from GSuite user’s custom attribute values.
Now you can configure your Application/Pipeline permissions as you need.
Passing GSuite Groups as roles in explicit Authorization
The procedure to use GSuite groups in Spinnaker authorization is,
On GCP cloud,
- Enable the Google Admin SDK
- Create a Service account
On GSuite,
- Authorize Service account to access GSuite groups On Spinnaker Halyard,
- Configure Authorization as ‘GOOGLE’type
- Enable authorization
Procedure in GCP
- Enable the Google Admin SDK.
Go to Google Admin SDK URL [https://console.cloud.google.com/apis/library/admin.googleapis.com] and enable the API by clicking ‘Enable’ button. - In GCP console [https://console.cloud.google.com/], create a Service account.
a. GCP Main Menu > IAM & Admin > Service Accounts > Create service account
In ‘Create Service account page’, fill in the values as given in the picture and click ‘Create’; This should download the private key for the new service account. This file will be needed later during Spinnaker Halyard configuration.
b. Edit the recently created Service account and enable Domain-wide Delegation (DwD)
c. Make a note of the Client-ID of the new Service account. This will be used to configure GSuite API access.
Procedure in GSuite
- Grant Service account access to the GSuite Directory API in the GSuite Admin console.
Google Admin Main Menu > Security > Under Advanced Settings, Click ‘Manage API client access’. Under Client Name, enter the Client-ID noted in the above steps. Under ‘One or More API Scopes’, enter the value ‘https://www.googleapis.com/auth/admin.directory.group.readonly‘. Now, click ‘Authorize’.
Procedure in Spinnaker Halyard
- Configure Halyard to use explicit Authorization.
a. Copy the Service Account’s json file to the Halyard machine. Now set the environment variablesspinnaker@halyard:~/.hal$ cat > vars.gsuite <<-EOF #GSuite Groups for Authz ADMIN=sagayaraj.d@opsmx.io CREDENTIALS=/home/spinnaker/.hal/saml/my-orbit_spindd-fiat.json DOMAIN=opsmx.io EOF spinnaker@halyard:~/.hal$ source vars.gsuite
- Run the below hal securitycommands
spinnaker@halyard:~/.hal$ hal config security authz google edit \ --admin-username $ADMIN \ --credential-path $CREDENTIALS \ --domain $DOMAIN spinnaker@halyard:~/.hal$ hal config security authz edit --type google spinnaker@halyard:~/.hal$ hal config security authz enable
It is important to ensure the Authentication configuration does not have any roles related fields mapped. If they are present, you may see unexpected roles being displayed in Spinnaker. So, review the ~/.hal/config file as below and remove the fields ‘roles’ and ‘rolesDelimiter’ if they are present.
spinnaker@halyard:~/.hal$ cat ~/.hal/config | grep 'saml' -A15 saml: enabled: true metadataLocal: /home/spinnaker/.hal/saml/GoogleIDPMetadata-opsmx.io.xml issuerId: Spindd.Dev keyStore: /home/spinnaker/.hal/saml/saml.jks keyStorePassword: spin@123 keyStoreAliasName: saml serviceAddress: https://spindd.opsmx.com:30084 userAttributeMapping: firstName: firstName lastName: lastName roles: spinnakerRoles #Remove this line rolesDelimiter: ',' #Remove this line
Now apply the changes with hal deploy apply command and check Spinnaker authentication.
Once Spinnaker has applied the changes, login to Spinnaker and then check the URL – https://spin dd.opsmx.com:30084/auth/user
JSON output shows the groups of the logged-in user from GSuite under ‘roles’ element.
{ "email": "sagayaraj.d@opsmx.io", "username": "sagayaraj.d@opsmx.io", "firstName": "Sagayaraj", "lastName": "David", "roles": [ "engineering", "test" ], "allowedAccounts": [ "k8s-qa-spin", "saga-azure-account" ], "enabled": true, "authorities": [ { "authority": "engineering" }, { "authority": "test" } ], "accountNonExpired": true, "credentialsNonExpired": true, "accountNonLocked": true }
At this point, if you create a new application or edit an application in Spinnaker, you should see that ‘Permissions’ field is visible with drop-down values being populated from GSuite user’s groups.
Now you can configure your Application/Pipeline permissions as you need.
Caution when using GSuite Groups and Custom Attributes together in Authorization
In case you have set ‘roles’ attribute in SAML authentication and you have also enabled explicit Authorization, then Spinnaker is going to merge the custom attribute values and groups for you.
Login to Spinnaker and then check the URL – https://spindd.opsmx.com:30084/auth/user JSON output shows the groups of the logged-in user from GSuite and Custom Attribute values under ‘roles’ element.
{ "email": "sagayaraj.d@opsmx.io", "username": "sagayaraj.d@opsmx.io", "firstName": "Sagayaraj", "lastName": "David", "roles": [ "spinnaker_admin", "spinnaker_user", "engineering", "test" ], "allowedAccounts": [ "k8s-qa-spin", "saga-azure-account" ], "enabled": true, "authorities": [ { "authority": "spinnaker_admin" }, { "authority": "spinnaker_user" }, { "authority": "engineering" }, { "authority": "test" } ], "accountNonExpired": true, "credentialsNonExpired": true, "accountNonLocked": true }
The same roles are refelected in Spinnaker New/Edit Application.
Therefore, it is advised that you go with either Custom Attribute values or GSuite Groups.
- If you choose to retain only custom attribute, Authorization type should be ‘EXTERNAL’ and in Authentication ‘roles’ field should be set to Custom Attribute.
- If you choose to retain only GSuite Groups, ensure ‘roles’ field is not set under Authentication and ‘GOOGLE’ is set as Authorization type
References
SAML Auth – https://s8.staging-host.com/opsmx_blog/saml-authentication-on-spinnaker-using-gsuite/
Auth G-Groups – https://www.spinnaker.io/setup/security/authorization/google-groups/