Target audience
The target audience for this post is someone who already know what is Spinnaker and is planning to configure authentication (AuthN) for his Spinnaker instance.
Introduction
At the moment, AuthN and Authorization (AuthZ) are still work in progress on the Spinnaker project. You can see in the roadmap the Google team is in charge. They naturally implemented OAuth2 support for AuthN and AuthZ through Google Apps. But as the implementation is based on Spring Security, using another OAuth2 provider is not really complex. Everything is basicaly explained in the docs but I’d like to cover in detail how to use GitHub for AuthN and Authz.
Context
I consider you already have a running instance of Spinnaker.
I will describe my setup which is based on the official AMI deployed on AWS.
AWS
Security group
The following ports are open : 9000
(deck), 8084
(gate), 8087
(rosco) for 0.0.0.0/0
.
Route53
I added the DNS alias spinnaker.mydomain.net
for the IP of my running instance.
ELB
I do not use an ELB in front of my Spinnaker instance.
GitHub
If you want to set up AuthN and AuthZ through GitHub, you must have a GitHub organization.
Typically you want all your organization members to be able to login and use GitHub teams to define ACL.
At the moment, once you will have configured AuthN, everyone with a GitHub account will be able to log into your Spinnaker with Read-Only (RO) rights. You will be able to give Read-Write (RW) to all your organization members or a few ones (using GitHub teams) but everyone will be able to see your infrastructure, pipelines, etc … A brand new service, fiat should solve this security issue and give the ability to define really fine ACL but it’s currently under development. The solution I chose to fix this is to restrict the access to my Spinnaker instance through a VPN (I will not detail this part in this article). |
EDIT: Another solution to restrict access is to use the userInfoRequirements
parameter as explained in the documentation. The GitHub User retrieved when authenticated has a company
field. You can link your GitHub organization to your GitHub profile setting in your profile as company @myOrganisation
. To restrict access to your GitHub organization @myOrganization
you can set this in your `gate-local.yml`file :
userInfoRequirements:
company: @myOrganization
This is not really secure! Any GitHub user can set his Company in his GitHub profile. He does not have to be a member of your GitHub organization. A GitHub organization administrator can not change a user profile. This is a tricky hack. You could also use another field like bio or city but be aware all those fields are public, so do not use a secret value to restrict access.
|
the userInfoRequirements should definitively be used to restrict access. If in the GitHub profile there were the organizations a user belongs to, it would be secure.
|
OAuth application
You need to register a new OAuth application on this page https://github.com/organizations/yourOrg/settings/applications
.
The application name and the description will be displayed to the users the first time they autenticate theirself.
The two more important fields to fill are :
-
Homepage URL :
http://spinnaker.mydmomain.net:9000
aka deck URL -
Authorization callback URL :
http://spinnaker.mydmomain.net:9000/gate/login
which is based on gate URL
You can notice I used explicit ports, this is because I don’t use an ELB in front on my instance. Otherwise, the ELB might redirect the port 80
to 9000
and I would not have to use explicit ports.
Once your configuration saved, you should have two important informations now : Client ID
and Client Secret
. This will be used later in Spinnaker configuration.
Access token
This is required for AuthZ.
Spinnaker will use GitHub API to check users membership. To consume GitHup API, an access token is required so you need to generate one.
Unfortunately, it’s not currently possible to use the clientId
and clientSecret
as credentials. You must generate a personal token on this page https://github.com/settings/tokens
.
You can use your personal GitHub account ou create a specific one for a kind of bot, as you wish, the only requirement is to select the read:org
scope for this token.
Spinnaker
Apache
Your Spinnaker instance should be available without a ssh tunnel so so you should have set up your Apache like specified in the official doc.
spinnaker-local.yml
Here are the important configs to set :
services:
default:
# These defaults can be modified to change all the spinnaker subsystems
# (clouddriver, gate, etc) at once, but not external systems (jenkins, etc).
# Individual systems can still be overridden using their own section entry
# directly under 'services'.
protocol: http # Assume all spinnaker subsystems are using http
host: 0.0.0.0
deck:
# Frontend configuration.
# If you are proxying Spinnaker behind a single host, you may want to
# override these values. Remember to run `reconfigure_spinnaker.sh` after.
baseUrl: http://spinnaker.mydomain.net:9000
gateUrl: ${services.deck.baseUrl}/gate
auth:
enabled: true
gate-local.yml
Create a gate-local.yml
file if you do not have one and set it like that :
spring:
oauth2:
client:
preEstablishedRedirectUri: http://spinnaker.mydomain.net:9000/gate/login
useCurrentUri: false
clientId: theClientIdYouGotEarlier
clientSecret: theClientSecretYouGotEarlier
userAuthorizationUri: https://github.com/login/oauth/authorize # Used to get an authorization code
accessTokenUri: https://github.com/login/oauth/access_token # Used to get an access token
scope: read:org,user:email
resource:
userInfoUri: https://api.github.com/user # Used to the current user's profile
userInfoMapping: # Used to map the userInfo response to our User
email: email
firstName: name
lastName:
username: login
auth:
groupMembership:
service: github
github:
organization: yourOrganization
baseUrl: https://api.github.com
access_token: theTokenYouGotEarlier
In GitHub a user is defined by his login, not by his email (even if you cannot create two GitHub account with the same email). firstName
, lastName
are also optional, that’s why we remapped inforrmation using the userInfoMapping
conf.
Let’s test it
Don’t forget to run the reconfigure_spinnaker.sh
script to regenerate deck settings.js
file and then restart spinnaker and you should be able to authenticate yourself using GitHub!
You can check your configuration is ok on http://spinnaker.mydomain.net:9000/gate/env
.
Each GitHub user who wants to authenticate itself in Spinnaker must have a public email (set here). If he does not, he will be indefinitively redirected like an infinite loop. |
Once authenticated you could see your "profile" using this url http://spinnaker.mydomain.net:9000/gate/auth/user
.