Skip to main content

Authentication

Authentication enable the typegate to identify the user making the request and share some contextual data (called later "context" or "claims"). This data can then be used by policies or injected into various fields. Authenticated requests must use the Authorization header to provide a token in one of the following format.

Basic authentication

Basic authentication is the simplest way to authenticate requests. It is done by sending a base64 encoded string of your username and password in the authorization header. Recall that base64 encoding is not encryption and can be easily reversed, thus the traffic must be encrypted with SSL/TLS when using basic authentication as your password will otherwise be visible.

ComponentsValues
SecretsBASIC_[username]=password
HeaderAuthorization: Basic base64(username:password)
Context{ username }
Loading...

JWT authentication

A more secure way to authenticate requests is to use JSON Web Tokens. The context of a user is signed with a secret key and the typegate will verify the signature to ensure the context has not been tampered with. The JWT is then sent in the authorization header.

The JWT is usually generated by an external identity provider (IdP) such as Keycloak or Auth0 and limited in time. The typegate will check that the exp (expiration time) and nbf (not before) are valid if they exist in the context. The logic of refreshing expired tokens is left to the user or the IdP client library being used.

The typegate supports the most frequently used algorithms for signing the JWT and can be imported as using "jwk", "raw", "pkcs8" or "spki" formats (see SubtleCrypto documentation). For instance, an asymmetric key pair can be generated with the following command:

const keys = await crypto.subtle.generateKey(
{ name: "ECDSA", namedCurve: "P-384" },
true,
["sign", "verify"],
);
const publicKey = await crypto.subtle.exportKey("jwk", keys.publicKey);
// save keys.privateKey for later use
console.log(JSON.stringify(publicKey));
// in typegraph: Auth.jwt("keycloak", "jwk", {"name": "ECDSA", "namedCurve": "P-384"})

Even though, asymmetric encryption is recommended, HMAC-SHA256 is so commonly used that an alias is provided for it.

ComponentsValues
Secrets[authentication]_JWT=secret
HeaderAuthorization: Bearer token
Context{ your_own_content }
Loading...

Note that for the sake of the demo, the token has no expiration time. Tokens should always be shorted lived and refreshed frequently to reduce the risk of unexpected access.

OAuth2 authorization

OAuth2 allows a user to grant limited access to their resources on one site, to another site, without having to expose their credentials. It is commonly used when the typegate needed to access restricted information in third-parties such as Google or GitHub.

Most of the time, the OAuth2 is managed by your identity provider and relies on the JWT authentication as explained above. However the typegate provides a simple way to handle the OAuth2 flow without IdP or when the system should be lightweight.

ComponentsValues
Secrets[authentication]_CLIENT_ID=client_id, [authentication]_CLIENT_SECRET=client_secret
HeaderAuthorization: Bearer token
Context{ content_from_your_idp }

The OAuth2 authorization system requires you to have a redis instance configured for the typegate to store states. See configuration for more details.

Token flow

The typegate uses PKCE based authorization. The steps are the following:

  1. Redirect the user to `https://[typegate].metatype.cloud/[typegraph]/auth/[authentication] with the following search parameters:
  • client_id: The client id of your application defined in the typegraph
  • redirect_uri: The redirect URI of your application defined in the typegraph
  • state: A random string used to prevent CSRF
  • code_challenge: A hashed of the string used as a code verifier
  • code_challenge_method: Set to S256
  • scope: The scope of the token (optional)
  1. When the user has completed the flow, the typegate will redirect the user to https://your-website.com/login with an authorization code that you can exchange for a token from the typegate as follows. It is done by making a POST request to https://[typegate].metatype.cloud/[typegraph]/auth/token with the following body:
  • code: The authorization code from the typegate
  • code_verifier: The inital code verifier
  • grant_type: Set to authorization_code
  • client_id: The previous client id
  • redirect_uri: The previous redirect URI
const claims = await fetch(
"https://[typegate].metatype.cloud/[typegraph]/auth/token",
{
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
code: "code",
code_verifier: "code_verifier",
grant_type: "authorization_code",
client_id: "client_id",
redirect_uri: "redirect_uri",
}),
},
);
const { token } = await claims.json();

The returned token will have the following fields:

  • access_token: Used to make authentified requests
  • refresh_token: Used to get another token
  • token_type: Set to Bearer
  • expires_in: Expiration time
  • scope: The scope of the token
  1. The access_token can then be used as JWT in the Authorization header of your requests to make authentified calls.
Loading...
  1. When the token is expired, you can claim another token by using your refresh_token by making a POST request to the token endpoint [https://[typegate].metatype.cloud/[typegraph]/auth/token] with the following body:
  • grant_type: Set to refresh_token
  • refresh_token: The previously received refresh token
  • scope: The new token scope (optional)
const claims = await fetch(
"https://[typegate].metatype.cloud/[typegraph]/auth/token",
{
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
grant_type: "refresh_token",
refresh_token: "refresh_token",
}),
},
);
const { token } = await claims.json();

OpenID Connect

OpenID Connect is an authentication layer on top of OAuth2. It is used to verify the identity of the user and retrieve basic information about them. You can add openid to the OAuth2 scope and you will receive an id_token in the response. The id_token is a JWT that contains the user's information and is signed by the IdP.

Embedded providers

Frequent OAuth2 providers are embedded and can be directly used in the typegraph.

from typegraph.graph.params import Auth

Auth.oauth2(
provider="github",
scopes=["openid", "profile", "email"],
clients=[
{
"id_secret": "APP_CLIENT_ID",
"redirect_uri_secret": "APP_REDIRECT_URI",
}
],
)

The available providers are:

  • digitalocean
  • discord
  • dropbox
  • facebook
  • github
  • gitlab
  • google
  • instagram
  • linkedin
  • microsoft
  • reddit
  • slack
  • stackexchange
  • twitter