Skip to main content

OpenID Connect

OpenID Connect (OIDC) allows for discovery of authentication services that follow the OpenID Connect Discovery Specification. Projects can use the OIDC endpoint, which will always end in .well-known/openid-configuration, to read the asymmetric keys required to validate bearer tokens from a number of third parties.

Getting started

One common provider of OIDC services is Auth0. These instructions will take you through setting up Auth0 as an OIDC provider as an example of how you might configure your own. Microsoft Azure, Google Identity and many other services provide compliant endpoints and authorization tokens.

To get started, you'll need an Auth0 account and an active project. Once everything is configured Auth0 will issue your application a JWT, which is sent as a Bearer token, validated and made available to your custom queries. Your Auth0 user's passwords won't be shared, and will only be able to read the base and custom claims you make available on your tokens.

Creating a service connection

In your project, in the Home tab, select Connect Service. Select OpenID Connect as the service provider and then fill out the configuration screen.

Example of OIDC service config settings

  • For Issuer URL use your Auth0 tenant domain, for example, https://dev-fii3u88nb.us.auth0.com/ In this example, dev-fii3u88nb is the tenant name which can be found under Settings -> Tenant Information -> Tenant Name.
  • For OpenID Configuration URL use your Auth0 tenant domain with the openid-configuration path, for example, https://dev-fii3u88nb.us.auth0.com/.well-known/openid-configuration
  • For ID Claim use the JWT subject claim, sub. This claim is often used as a unique identifier of the bearer of the token.

Note an audience has been created for you. You'll need to provide this url to Auth0 to create a unique connection that can be validated. This audience also contains the name configured for the service, so if you delete it, you will effectively invalidate all your Auth0 tokens that were signed for this audience. This is an important safeguard to prevent unintended access.

Select save when you've copied the audience and have finished. You can always return to this screen later.

Creating a role for your Auth0 connection

In order for your Auth0 connection to provide access to API resources you'll need to create a custom role and add permissions to it. You'll also need to take advantage of the role conditions to ensure that requests coming through with Auth0 claims get this custom role assigned to them. That can be done with this JSON snippet.

{
"StringEquals": {
"claims:aud": "https://dev-fii3u88nb.us.auth0.com/"
}
}

Creating an Auth0 API connection

In Auth0, go to Applications > APIs then select Create API. On the next screen use the audience from the service configuration screen as the Identifier and be sure you use the default RS256 encryption algorithm.

Now you're ready to test your connection. Go to the Test tab for your API connection, and copy the provided curl command shown at the bottom of the page.

Paste the copied command into your terminal and replace http://path_to_your_api/ with api.takeshape.io/project/PROJECT-ID/auth/me.

Run the edited command.

If the test succeeds your claims will be echoed back to you with additional data used internally to handle the claims.

Running this command uses a special machine-to-machine access token in the request that validates that the service configuration is correct and the tokens from Auth0 are being processed.

Remember, all the data in a JWT is effectively public, so nothing in this token or in your Auth0 data model should be considered sensitive.

Here's a sample of the request and expected response.

Incorporating claims

Your token will provide a number of claims. In short, these are data points from your verified token. They are customizable, so they won't be the same for every provider. The userinfo_endpoint will be auto-discovered if your openid-configuration provides one, and will then extend your basic bearer claims with those.

Base claims

A full set base claims from Auth0 might look like this:

{
"iss": "https://dev-cy9w1mxg.us.auth0.com/",
"sub": "auth0|60845b2cb1cc580071d093dc",
"aud": [
"https://api.takeshape.io/project/5a0614fc-9519-4dbe-976a-99622dc4fe37/auth-0",
"https://dev-cy9w1mxg.us.auth0.com/userinfo"
],
"iat": 1622670727,
"exp": 1622757127,
"azp": "1VyUowW88mxDvmmhWeaSyVv5FJRqE9IK",
"scope": "openid profile email",
"sub": "auth0|60845b2cb1cc580071d093dc",
"nickname": "John Smith",
"name": "person@example.com",
"picture": "<gravatar-url>",
"updated_at": "2021-05-25T13:48:48.540Z",
"email": "person@example.com",
"email_verified": true
}

Sample use of claims in a schema

You can now incorporate OIDC claims into your schema. The following sample code shows how you might use claims.sub to prepopulate an ID value for mutating and querying profile data that is stored in a shape called Profile.

{
"queries": {
"getMyProfile": {
"shape": "Profile",
"resolver": {
"name": "shapedb:find",
"service": "shapedb",
"options": {"model": "Profile"},
"args": {
"ops": [{
"path": "where.id.eq",
"mapping": "$claims.sub"
}]
}
},
"description": "Get a profile using a claim."
}
},
"mutations": {
"createMyProfile": {
"shape": "Profile",
"resolver": {
"name": "shapedb:create",
"service": "shapedb",
"options": {"model": "Profile"},
"args": {
"ops": [{
"path": "where.id.eq",
"mapping": "$claims.sub"
}]
}
},
"description": "Create a profile, id'd by a claim.",
"args": {
"type": "object",
"properties": {
"id": {
"type": "string"
},
"firstName": {
"type": "string"
},
"lastName": {
"type": "string"
}
}
}
}
}
}