Authentication Architecture
Authentication
There are three basic players in Spinnaker’s authentication workflow:
Deck: Spinnaker’s UI. Consists of a set of static HTML, JavaScript, and CSS files. Generally served from an Apache server, but there is nothing special about Apache that makes Deck work. Replace with your favorite HTTP(S) server if you’d like.
Gate: Spinnaker’s API Gateway. All traffic (including traffic generated from Deck) flows through Gate. It is the point at which authentication is confirmed and one point (of several) where authorization is enforced.
Identity Provider: This is your organization’s OAuth 2.0, SAML 2.0, or LDAP service. X.509 client certificates can be used in addition to any of these services or as a standalone identity provider.
Workflow
Deck is a Javascript Single Page Application (SPA). This means that when a user leaves the page to enter their credentials, the entire application gets loaded again when they return. As a result, the process below involves numerous redirects between the three parties (Deck, Gate, and the Identity Provider).
Browser requests Deck’s landing page:
https://deck.url:9000/
Deck checks for the user’s identity:
https://gate.url:8084/auth/user
. Specifically, a user is logged in if the response contains a JSON object with a non-null “username” field./auth/user
is an unprotected URL but will only return the currently logged in user.If a user is found - all done!
Without a user logged in, Deck requests a protected URL:
https://gate.url:8084/auth/redirect?to=https://deck.url:9000
.
- Given that the URL is protected, Gate sees that there is no logged-in user, so it issues an HTTP 302
redirect to an authentication-method-specific page. It saves the requested URL
(
https://gate.url:8084/auth/redirect?to=https://deck.url:9000
) in the session state.
In the case of LDAP, the
/login
page is hosted in Gate and is a basic form asking for credentials. Gate attempts to establish a session (preferably over SSL) with the LDAP server, sending the username and password. If successful, the session is established. Otherwise, a “Bad Credentials” exception is thrown. For SAML/OAauth methods, these will redirect to the appropriate login page for the IDP.The user logs into the authentication provider.
The authentication provider sends a request back to Gate, usually through redirects of the user’s browser.
Gate processes the received data. This can include making additional requests to confirm the user’s identity.
Upon successful processing, the user is now considered logged in. Gate retrieves the originally requested URL from the session state. It issues an HTTP 302 to that URL (
https://gate.url:8084/auth/redirect?to=https://deck.url:9000
).The request from the browser hits the API gateway, along with the session cookie from the newly logged in user. The
to
query parameter is validated to be the associated Deck instance, and a final HTTP 302 is sent, directing the user to thehttps://deck.url:9000
.
- Repeat this process from step 1. Now, the response from
https://gate.url:8084/auth/user
will contain a proper JSON object and the rest of the application will proceed to load.
OAuth Workflow
The OAuth specification defines numerous flows for various scenarios. Spinnaker utilizes the authorization code flow, more commonly known as the three-legged OAuth. The three-legged OAuth flow looks like:
User attempts to access a protected resource.
Gate redirects to OAuth provider, passing the following important bits:
client_id
: A pre-established identifier for this Gate instance.redirect_uri
: Where to send the user after login. Must be accessible by the user’s browser.
Gate attempts to intelligently guess the
redirect_uri
value, but outside components like SSL terminating load balancers can cause this guess to be wrong. See SSL documentation for how to fix this.response_type=code
: Indicating that we are performing the three-legged OAuth flow.scope
: What data or resources Gate would like access to. This is generally something likeemail profile
to access the user’s email address.
OAuth provider prompts user for username & password.
sequenceDiagram participant Deck participant Gate participant IdentityProvider participant ResourceServer Deck->>+IdentityProvider: User sends credentials IdentityProvider->>-Deck: Confirms client_id 'foo' can access user's information Deck->>+IdentityProvider: User confirms IdentityProvider->>-Deck: HTTP 302 to https://gate.url/login?code=abcdefOAuth provider confirms that the user is granting Gate access to their profile.
Using the
redirect_uri
, the OAuth provider redirects the user to this address, providing an additionalcode
parameter.
Gate uses this
code
parameter to request an access token from the OAuth provider’s token server.Gate uses the access token to request user profile data from the resource server (
security.oauth2.resource.userInfoUri
).Gate uses the
userInfoMapping
to extract specific fields from the response, such as the username and email address, and associates it with the established session cookie with the user. See UserInfoMapping below.
The authorization code flow is the most secure way to get this data, because the access token is never revealed outside of the server using it.