Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Updated Auth0 Recipe: Improved Steps, Service Account Tokens, and Testing #727

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
102 changes: 89 additions & 13 deletions docs/recipes/authentication/1-auth0.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -37,16 +37,20 @@ Before continuing, ensure you have:

## Recipe

### Step 1. Create a new Auth0 Action
### Step 1. Create a new Auth0 application
From your Auth0 dashboard, click `Applications` in the sidebar and then click on `Create Application`. Enter a name for your application, then choose the application type that best suits your needs.

From your Auth0 application's dashboard, click `Action` in the sidenav and choose `Flows`.
After creating the application, go to `APIs` in the sidebar and create a new API with your GraphQL endpoint as the identifier.

Create a new `Login` flow and then choose the `Custom` option and click `Create Action` before entering a name for your
Action.
### Step 2. Create a new Auth0 Action

Then, modify the `onExecutePostLogin` function to the following:
From your Auth0 dashboard, click `Actions` in the sidebar and choose `Triggers`.

```typescript
Under `Sign Up & Login`, select the `post-login` trigger, click on the `+` icon, and then choose `Built from Scratch` to create a new Action.

Enter a name for your Action such as `Hasura JWT Claims` and paste the following code:

```javascript
exports.onExecutePostLogin = async (event, api) => {
const namespace = "claims.jwt.hasura.io";
// Here, you'll need to fetch the user's role from Hasura DDN using an admin-level authenticated request
Expand All @@ -55,7 +59,15 @@ exports.onExecutePostLogin = async (event, api) => {
const user_role = "user"; // the role returned from your request ☝️
api.idToken.setCustomClaim(namespace, {
"x-hasura-default-role": user_role,
"x-hasura-allowed-roles": ["user"],
"x-hasura-allowed-roles": [user_role],
"x-hasura-user-id": event.user.user_id,
// Add any other custom claims you wish to include
});

// Set the necessary access token claims for Hasura to authenticate the user
api.accessToken.setCustomClaim(namespace, {
"x-hasura-default-role": user_role,
"x-hasura-allowed-roles": [user_role],
"x-hasura-user-id": event.user.user_id,
});
};
Expand All @@ -75,7 +87,7 @@ more information on which values are required, check the

:::

### Step 2. Update your AuthConfig
### Step 3. Update your AuthConfig

Update your AuthConfig object to use JWT mode and your
[Auth0 JWKs](https://auth0.com/docs/secure/tokens/json-web-tokens/json-web-key-sets):
Expand All @@ -92,7 +104,8 @@ definition:
location: "/claims.jwt.hasura.io"
issuer: "<your Auth0 tenant's URL>"
key:
jwkFromUrl: "https://<your Auth0 tennant's URL>/.well-known/jwks.json"
jwkFromUrl: "https://<your Auth0 tenant's URL>/.well-known/jwks.json"
audience: ["<your GraphQL endpoint>"]
tokenLocation:
type: Header
name: Auth-Token
Expand All @@ -104,11 +117,74 @@ Then, create a new build of your supergraph:
ddn supergraph build local
```

### Step 3. Test your configuration
### Step 4. Service account access token

In certain cases, you may need to generate a service account access token to access your Hasura DDN supergraph when performing backend operations. You can do this by creating a new Auth0 application named `Service Account` with a type of `Machine to Machine Applications`.

After creating the application, go to `Triggers`, located underneath `Actions` in the sidebar, and click on the `credentials-exchange` trigger. Similar to the `post-login` trigger, create a new Action and paste the code below:

```javascript
exports.onExecuteCredentialsExchange = async (event, api) => {
const namespace = "claims.jwt.hasura.io";

const service_role = "service_account";

api.accessToken.setCustomClaim(namespace, {
"x-hasura-default-role": service_role,
"x-hasura-allowed-roles": [service_role],
});
};
```

This will generate a new JWT token with the `service_account` role which can then be used to access your Hasura DDN supergraph.

You can generate a new access token using the following Python code:

```python
import http.client

conn = http.client.HTTPSConnection("<Auth0 domain>")

payload = "{\"client_id\":\"<client id>\",\"client_secret\":\"<Auth0 Client Secret>\",\"audience\":\"<your GraphQL endpoint>\",\"grant_type\":\"client_credentials\"}"

headers = { 'content-type': "application/json" }

conn.request("POST", "/oauth/token", payload, headers)

res = conn.getresponse()
data = res.read()

print(data.decode("utf-8"))
```

The response will look like:
```json
{
"access_token": "<service account access token>",
"token_type": "Bearer"
}
```

You can modify your metadata to allow the `service_account` role to access the necessary models.

:::tip Best Practices for Service Accounts

Instead of granting a service account full admin access, create a custom role with only the necessary permissions. This approach follows the principle of least privilege, thereby limiting potential impact in case of any errors or oversights.

:::




### Step 5. Test your configuration

Go to `Extensions` in your Auth0 dashboard and search for `Auth0 Authentication API Debugger` to test your configuration.

Choose your application in the `Configuration` tab, copy the `Callback URL` provided, and paste it into the `Allowed Callback URLs` field as well as into the `Allowed Logout URLs` field in your Auth0 application settings.

After configuring the callback URL, go to the `OAuth2/ OIDC` tab and enter your GraphQL endpoint in the `Audience` field. Finally, click on the `OAUTH2 / OIDC LOGIN` button to generate a new token.

Generate a new JWT by logging into your application. These values aren't typically displayed to users, so you'll need to
log them while in development. You can then add that value as a header in the console and test any permissions you have
in your metadata.
After authenticating, you should see the JWT token underneath `Hash Fragment` which you can use to test your auth configuration in Hasura Console. You'll also see the custom claims you've set in the `Access Token` section underneath the `payload` key.

## Wrapping up

Expand Down