Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

DC/OS - authentication vs. api token

Tags:

marathon

dcos

As far as i know, DC/OS has two different types of tokens:

  • authentication token: retrieved via a login through https://public-master-ip/login?redirect_uri=urn:ietf:wg:oauth:2.0:oob. This token is used to retrieve api tokens.

  • api token: retrieved via a post call to https://public-master-ip/acs/api/v1/auth/login with the authentication token in the request body. This token is used to authorize calls against the apis. Such a token expires after 5 days.

My questions are

  1. Are my assumptions correct?
  2. Does a authentication token expire? If so, when and is there a way to refresh it?
like image 617
sjahreis Avatar asked Sep 17 '16 11:09

sjahreis


Video Answer


1 Answers

Let me first define the goal of the current (1.8) Open DC/OS authentication procedure and then walk through your assumptions. I'll answer your questions after that.

Goal

The goal of the current Open DC/OS authentication procedure is to use Auth0 infrastructure for triggering a single sign-on authentication flow against one of three popular identity providers, and have the result reported back to your DC/OS cluster. If the DC/OS cluster is happy with the result, it will emit an authentication token specifically adjusted to that individual cluster.

Comments on your assumptions

authentication token: retrieved via a login through https://public-master-ip/login?redirect_uri=urn:ietf:wg:oauth:2.0:oob. This token is used to retrieve api tokens.

That's roughly true. However, what you call "authentication token" actually is an OpenID Connect ID Token emitted by an OpenID Connect identity provider.

Let us take this one slowly, as it is a little involved.

What happens behind the scenes is an OpenID Connect single sign-on authentication flow.

More precisely, the DC/OS UI displays an iframe that loads a piece of JavaScript hosted by Auth0, which -- when executed in your browser -- performs the so-called implicit flow (which is one of three specified OpenID Connect authentication flow types).

By the end of this flow(*) the JavaScript code executed in your browser receives a so-called OpenID Connect ID Token (from the identity provider, of course, which is Auth0 in this case). This token is a JSON Web Token (JWT, see RFC7519) signed with the private key of the identity provider (in this case it actually is Auth0, which basically proxies other identity providers such as Google Accounts).

The piece of JavaScript that receives the ID token then -- as you say -- POSTs the ID Token to your DC/OS cluster (to https://public-master-ip/acs/api/v1/auth/login). The receiving end is a web application behind DC/OS' Admin Router (the latter is just a pimped nginx). That web application inspects the ID Token's payload (which is JSON) and finds the key/value pair "iss": "https://dcos.auth0.com/". So it knows who (pretends to) have issued that token! Then it goes ahead and fetches https://dcos.auth0.com/.well-known/openid-configuration (wooo, where does it know that URL from? This is magic defined by OpenID Connect Discovery 1.0 and RFC5785). That JSON document there defines a JSON Web Key Set (JWKS) document (specified via RFC7517), revealing the public key corresponding to the private key that had (supposedly) signed the ID Token. So, that web application goes ahead and fetches the public key directly from the identity provider (through HTTPS). It then uses that public key to verify the cryptographic signature of the ID Token (and it checks the expiration time, too, of course). If ID Token validation passes, the DC/OS web application I talked about rightfully assumes that the user agent that had sent the ID Token is successfully authenticated against Auth0. And, trusting Auth0, we rightfully assume that the user agent is authenticated against e.g. Google Accounts.

Only then it (the small web application in DC/OS I talked about) stores the identity within DC/OS, assigns a unique user ID, and emits the DC/OS authentication token. That token refers to the given identity via the named user ID.

(*)Note that the identity provider only emits the ID Token towards your browser after you have successfully authenticated yourself towards that provider (e.g. Google Accounts) and after you have given consent to share identity details with a third-party service.

api token: retrieved via a post call to https://public-master-ip/acs/api/v1/auth/login with the authentication token in the request body. This token is used to authorize calls against the apis. Such a token expires after 5 days.

In DC/OS terminology, this is the DC/OS authentication token. It is a JWT signed with a random key only known to your DC/OS cluster. The Admin Router in your DC/OS can validate such authentication tokens. Certain HTTP requests against Admin Router are only proxied to back-end services when they contain a valid authentication token in the request (hence, this token mainly serves authentication, but also a very basic coarse-grained authorization, if you want to say so). Otherwise, Admin Router will respond with a 401 (read: "not authenticated").

Answers to your questions

Are my assumptions correct?

I hope to have clarified

  • that what you call "authentication token" is an OpenID Connect ID Token (a JWT).
  • that what you call "api token" is what's called "DC/OS authentication token" in the DC/OS ecosystem (and it's technically a JWT, too).

Does a authentication token expire?

I read this question as "Does an OpenID Connect ID Token expire?" Yes, indeed! This is what the spec says about ID Token expiration:

exp -- REQUIRED -- Expiration time on or after which the ID Token MUST NOT be accepted for processing. The processing of this parameter requires that the current date/time MUST be before the expiration date/time listed in the value. Implementers MAY provide for some small leeway, usually no more than a few minutes, to account for clock skew. Its value is a JSON number representing the number of seconds from 1970-01-01T0:0:0Z as measured in UTC until the date/time. See RFC 3339 [RFC3339] for details regarding date/times in general and UTC in particular.

Note that the spec does not enforce a particular ID Token lifetime -- this is up to identity providers to set. In case of ID Tokens emitted by dcos.auth0.com I have just confirmed that

>>> exp = 1474742063
>>> iat = 1474310063
>>> lifetime_days = (exp - iat) / (60.0 * 60 * 24)
>>> lifetime_days
5.0

That is, the ID Token emitted by Auth0 expires after 5 days.

If so, when and is there a way to refresh it?

You can only obtain a new ID Token emitted by Auth0 by going through an OpenID Connect authentication flow involving one of the configured identity providers. That is, the (only) intended way to obtain such a token and pass it along to DC/OS is triggered through the DC/OS UI which starts the Auth0-based flow for you (well, you could technically hack this together yourself...).

Note that Enterprise DC/OS offers an OpenID Connect authentication flow that

  • directly communicates the ID Token securely between DC/OS and the identity provider (no user agent ever sees that ID Token).
  • enforces the usage of the optional nonce mechanism of OpenID Connect ID Tokens (described in the spec), introducing more conceptual security on multiple levels (e.g. mitigating replay attacks).

We will probably merge that functionality into Open DC/OS by one of the next releases (no promises at this point!).

I hope that helped, let me know if there are further questions.

like image 88
Dr. Jan-Philip Gehrcke Avatar answered Oct 19 '22 12:10

Dr. Jan-Philip Gehrcke