Skip to content

Secure your API with MaskinportenΒΆ

This how-to guides you through the steps required to secure your API using Maskinporten:

PrerequisitesΒΆ

Define scopesΒΆ

A scope represents a permission that a given consumer has access to.

Declare all the scopes that you want to expose in your application's NAIS manifest:

nais.yaml
spec:
  maskinporten:
    enabled: true
    scopes:
      exposes:
        # nav:helse/sykepenger/afp.write
        - enabled: true
          product: "helse"
          separator: "/"
          name: "sykepenger/afp.write"
        # nav:helse/sykepenger/afp.read
        - enabled: true
          product: "helse"
          separator: "/"
          name: "sykepenger/afp.read"

See the scope naming reference for details on naming scopes.

See the NAIS application reference for the complete specifications with all possible options.

Grant access to consumersΒΆ

Grant the external consumer access to the scopes by specifying their organization number:

nais.yaml
spec:
  maskinporten:
    enabled: true
    scopes:
      exposes:
        - name: "sykepenger/afp.read"
          enabled: true
          product: "helse"
          separator: "/"
          consumers:
            - orgno: "123456789"

Now that you have configured the scopes in Maskinporten, consumers can request tokens with these scopes. You will need to validate these tokens in your application.

Validate tokensΒΆ

Verify incoming requests from consumers by validating the JWT Bearer token in the Authorization header.

To validate a token, you can either:

Validate with TexasΒΆ

Texas is not enabled by default

See the Texas documentation for more information.

Send a HTTP POST request to the endpoint found in the NAIS_TOKEN_INTROSPECTION_ENDPOINT environment variable. The request must have a Content-Type header set to either:

  • application/json or
  • application/x-www-form-urlencoded

The body of the request should contain the following parameters:

Parameter Example Value Description
identity_provider maskinporten Always maskinporten.
token eyJra... The access token you wish to validate.
Token request
POST ${NAIS_TOKEN_INTROSPECTION_ENDPOINT} HTTP/1.1
Content-Type: application/json

{
    "identity_provider": "maskinporten",
    "token": "eyJra..."
}
Token request
POST ${NAIS_TOKEN_INTROSPECTION_ENDPOINT} HTTP/1.1
Content-Type: application/x-www-form-urlencoded

identity_provider=maskinporten&
token=eyJra...

The response is always a HTTP 200 OK response with a JSON body.

It always contains the active field, which is a boolean value that indicates whether the token is valid or not.

Success responseΒΆ

If the token is valid, the response will also contain all the token's claims:

Valid token
{
    "active": true,
    "exp": 1730980893,
    "iat": 1730977293,
    ...
}

Texas validates the standard claims. Other claims are not validated. Your application must validate these claims according to your own requirements.

Error responseΒΆ

If the token is invalid, the only additional field in the response is the error field:

Invalid token
{
    "active": false,
    "error": "token is expired"
}

The error field contains a human-readable error message that describes why the token is invalid.

Validate JWT manuallyΒΆ

Validating a JWT involves a number of steps. These steps are outlined and described below in a language- and framework-agnostic way.

Libraries for token validation

We recommend using a library in your language of choice to handle all the validation steps described below. Here are some recommended libraries:

Validation is also supported by many popular frameworks:

To validate the token, start by validating the signature and standard time-related claims.

Additionally, perform the following validations:

Issuer Validation

Validate that the iss claim has a value that is equal to either:

  1. the MASKINPORTEN_ISSUER environment variable, or
  2. the issuer property from the metadata discovery document. The document is found at the endpoint pointed to by the MASKINPORTEN_WELL_KNOWN_URL environment variable.

Audience Validation

The aud claim is not included by default in Maskinporten tokens and does not need to be validated. It is only included if the consumer has requested an audience-restricted token.

Only validate the aud claim if you want to require your consumers to use audience-restricted tokens. The expected audience value is up to you to define and must be communicated to your consumers. The value must be an absolute URI (such as https://some-provider.no or https://some-provider.no/api).

Signature Validation

Validate that the token is signed with a public key published at the JWKS endpoint. This endpoint URI can be found in one of two ways:

  1. the MASKINPORTEN_JWKS_URI environment variable, or
  2. the jwks_uri property from the metadata discovery document. The document is found at the endpoint pointed to by the MASKINPORTEN_WELL_KNOWN_URL environment variable.

Other Token Claims

Other claims may be present in the token. Validation of these claims is optional.

Scope ValidationΒΆ

You must validate the scope claim in the token, regardless of whether you're using Texas or validating JWTs manually.

The scope claim is a string that contains a whitespace-separated list of scopes. Validate that the scope claim contains the expected scope(s).

The semantics and authorization that a scope represents is up to you to define and enforce in your application code.