Skip to content

Scopes

A scope in Maskinporten terminology is equivalent to a distinct API. As an API provider, you will:

  • define scopes to be registered in Maskinporten
  • grant access to other organizations for your defined scopes

The notion of scope is loosely defined to allow semantic freedom in terms of API providers' own definition and granularity of access and authorization.

An external consumer that has been granted access to your scopes may then acquire an access_token with their own Maskinporten client, which they will need to acquire from DigDir on their own. Our NAIS clients are registered as part of the NAV organization and may only be used by NAV.

Spec

See the NAIS manifest.

Configuration

spec:
  maskinporten:
    enabled: true
    scopes:
      exposes:
        - name: "some.scope.read"
          enabled: true
          product: "arbeid"
          allowedIntegrations:
            - maskinporten
          atMaxAge: 120
          consumers:
            - orgno: "123456789"

  # required for on-premises only
  webproxy: true

Scope Naming Format

All scopes within Maskinporten are defined using the following syntax:

scope := <prefix>:<subscope>
Example scope
scope := nav:trygdeopplysninger

Prefix

The prefix for all scopes provisioned through NAIS will always be nav.

Subscope

A subscope should describe the resource to be exposed as accurately as possible (e.g. trygdeopplysninger or helseopplysninger).

The subscope may also be postfixed to separate between access levels, for instance read and/or write access (e.g. nav:trygdeopplysninger.write).

Absence of a postfix should generally be treated as strictly read access.

All subscopes for NAIS clients will have the following form:

subscope := <product><separator><name>

where separator is:

  • / if and only if name contains /.
  • : otherwise.
Subscope example

For the example configuration above where

  • product := arbeid
  • name := some.scope.read

the subscope will be the following:

subscope := arbeid:some.scope.read

which results in the scope:

scope := nav:arbeid:some.scope.read
Subscope example with different separator

If the name instead contains the / character, e.g:

  • name := some/scope.read

and the product is the same as before:

  • product := arbeid

the resulting subscope will be:

subscope := arbeid/some/scope.read

which results in the scope:

scope := nav:arbeid/some/scope.read

Audience Restrictions

If there are multiple APIs that are protected by the same scope, one might be susceptible to replay attacks.

One way to mitigate this is to require that tokens contain an aud claim with a unique value for each unique API. The API should reject requests with tokens that do not have this claim and expected value. This ensures that an access_token may only be used for a specific API.

The value of this must be defined by the API provider out-of-band from Maskinporten. It is thus the API provider's responsibility to inform any consumers of this expected value so that they can modify their requests accordingly.

See DigDir's documentation on audience-restricted tokens for more information.

Legacy

Info

This section only applies if you have an existing scope registered at the IaC repository

Migration guide to keep existing Maskinporten scope (NAIS application only)

The following describes the steps needed to migrate a scope registered in IaC repository.

Step 1 - Update your scope description in the IaC repository

  • Ensure the description of the scope registered in the IaC repository follows the naming scheme:
<cluster>:<metadata.namespace>:<metadata.name>.<subscope>

Step 3 - Deploy your NAIS application with Maskinporten provisioning enabled.

  • Ensure exposed scopes enabled and name matches the already exposed subscope

  • See configuration.

Step 4 - Delete your scope from the IaC repository

  • Verify that everything works after the migration
  • Delete the scope from the IaC repository in order to maintain a single source of truth.