Only this pageAll pages
Powered by GitBook
1 of 50

Naviga ID

Loading...

Loading...

Architecture

Loading...

Integrations

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Services

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Shared modules

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Client Credentials

Loading...

Access Token

Loading...

Loading...

Local development

Loading...

Post Mortem

Loading...

Introduction

Naviga ID (formerly IMID) is Naviga's SSO (Single Sign-on) authentication and authorization service for all content creation tools. Built on the industry standard of JSON Web Token, Naviga ID integrates with organization's existing identity provider using OpenID Connect. OpenID Connect ensures compatibility with all major identity providers such as Google, Facebook, Azure AD and many more.

Naviga ID also supports the OAuth2 standard Client Credentials which is used to obtain access tokens for machine-to-machine communication scenarios, such as import and export of material to and from Naviga's content services.

Routes

Authorization schema

Introduction

Naviga ID has a role based authorization schema. Each role in Naviga ID corresponds to one or more permissions. Roles are set up by Naviga.

When a user logs into Naviga ID, the groups a user belongs to in the organization's identity provider are imported into Naviga ID.

Via Naviga ID's Admin service, organization administrators can configure the mappings between org groups and one or more service roles. Mappings can also include a unit, and will in that case limit the resolved permissions to only be applied to that unit. A unit can be viewed as a sub-organization within an organization. A mapping can also be created without including a unit, in that case the resulting permissions will be global for the organization, meaning they are valid in all units.

Organization

Every user belongs to an organization, for example "the media group".

The name of the organization is also part of your Dashboard domain name (for example https://mediagroup.dashboard.infomaker.io)‌

Use case Content Creation: Content access can be based, depending on your needs, to have everything open to the entire organization or be based on unites (see below). Some rights are also role based, such as publish flow possibilities (from Writer 6.0).

In some Dashboard applications, it is also possible to share specified content with the entire organization. This way it is possible to make concepts available to everyone, or only specific units. As a user creates or modifies content, that content is automatically labelled with the user organization.

Unit

A unit is defined by the publication that the user is part of, for example "South News" or "North News" within the organization.

‌‌Use case Content Creation: Content access is based on all the user units. For example in an application such as Dashboard Article Search, a user that belongs to two units will see articles from both these units (filtering using suggest search on channels or units possible with configuration).

Access control is unit wide which means that everyone within a unit can see the same content, and everyone with the right to edit content can edit all content within a unit.

A user can belong to one or many units, but only one unit can be "active" at the time. As a user creates content, that content is automatically "labelled" with the active unit. In our recommended setup, this will also make the content access right set to that unit. If a user modifies content, the object will contain this information but the access right will not be modified.

With some Dashboard applications it is also possible to share content with all or any of the units the user belongs to.

It is also good to know that all Dashboard configurations are made per unit (installed and available apps, specific app configuration, workspaces etc).

Group

A group is defined by the working task that people are working with in the organization, for example reporters, editors etc. Groups are configured in the organization's identity provider.

Service Roles

Service Roles define the privileges for a specified service, for example what a Dashboard user can do. It could be power user, admin or read-only mode etc. Service Roles are global roles and defined by Naviga.

How roles are used is configured by your administrator: who can create, edit and delete concepts, who can create and edit lists, who can plan articles within the Publication Planner.

Use case Content Creation: In addition to defining privileges to specific functions, roles can also be used for setting workflow statuses (from Writer 6.0). This means that it is possible to allow internal journalists to publish without prior approval but contributors cannot publish directly for example. These workflow steps are fully customizable.

Service roles are not used for content access control.

Below is a schematic sketch of the difference between groups and service roles.

Customer Integration

Integration of an Identity Provider in Naviga ID using OpenID Connect requires some setup in the Identity Provider. Here you can find instructions for the most common providers and how to configure them to support Naviga ID.

IMSG

Service Authorization Lib

The organisation "mediagroup"
The unit "South News"
The group "editor"
The Service Role "dashboard:powerUser"

Admin API

Http Test Server

Hapi plugin

Routes

Custom Identity Provider

This document describes how to integrate a custom Identity Provider using OpenID Connect with Naviga ID.

Prerequisites

The party that wished to integrate with Naviga Login must have an identity provider compatible with the OpenID Connect 1.0 Core specification.

Specifically, the identity provider must support the OpenID Connect Authorization Code Flow.

Information for Infomaker

Information we need to integrate your OIDC application:

  • URL to your (.well-known/openid-configuration)

  • Client ID

  • Client secret

Information for the integrating party

Allowed callback URLs

The following URLs must be added to the integrating party’s Whitelisted Callback URLs or equivalent:

Allowed web origins

The following URLs must be added to the integrating party’s Allowed Web Origins or equivalent:

Health

/health

GET https://admin-api.imid.infomaker.io/v1/health

Health

Path Parameters

Name
Type
Description

Moving to a New Identity Provider

Retaining subject IDs in Naviga ID

Moving to a new identity provider will, most of the time, involve a new subject ID for the user, resulting in a new subject ID in Naviga ID as well. To retain the users Naviga ID subject ID, the http://infomaker.io/originalSubject claim can be added to the organization token. This claim should consist of the subject ID the user had in the previous identity provider.

When encountering the http://infomaker.io/originalSubject claim, Naviga ID will replace the previous subject ID stored internally with the subject ID found in the sub

Unauthorized

Unauthorized⇐ ServiceAuthorizationError

Unauthorized - extending the ServiceAuthorizationError error class

PublicMessage is set to 'Unauthorized' and the HttpCode is set to '401'.

Thrown when a user tries to request an endpoint with no access to it.

Extends: ServiceAuthorizationError

new Unauthorized(publicData, internalData)

Param

Type

Description

publicData

Object

Required - Data to show in the error

internalData

Object

Required - Private data that can be logged in the error

hapiReply(replyOrResponseToolkit, [extraPublicData]) ⇒ Object

Reply function to respond with the error

Overrides: ServiceAuthorizationError#hapiReply Returns: Object - Response - Response object

Param

Type

Default

Description

replyOrResponseToolkit

Object

Required - Response toolkit - For example 'h' in Hapi, which handles the response

extraPublicData

Object

{}

Extra public data to shown in the error message

OpenID provider metadata file
http://localhost:9091/v1/org/{orgName}/login-callback
https://imas.imid.infomaker.io/v1/org/{orgName}/login-callback
https://imas.stage.imid.infomaker.io/v1/org/{orgName}/login-callback
http://localhost:9091
https://imas.imid.infomaker.io
https://imas.stage.imid.infomaker.io

string

{
  "name": "Service name (admin-api).",
  "version": "Service version."
}
claim.
{
    "sub": "subject-id-from-current-idp"
    "http://infomaker.io/originalSubject": "subject-id-from-previous-idp"
    ...
}

IMSG and headers

Headers added by IMSG

Header

Description

Removed by SAL

authorization

Contains the service token.

Yes

Any headers not in the list will be forwarded to the service unmodified.

ConfigError

ConfigError⇐ ServiceAuthorizationError

ConfigError - extending the ServiceAuthorizationError error class

PublicMessage is set to 'Internal Server Error' and the HttpCode is set to '500'.

Thrown when building config variables while authorize.

Extends: ServiceAuthorizationError

new ConfigError(publicData, internalData)

hapiReply(replyOrResponseToolkit, [extraPublicData]) ⇒ Object

Reply function to respond with the error

Overrides: ServiceAuthorizationError#hapiReply Returns: Object - Response - Response object

AccessDenied

AccessDenied⇐ ServiceAuthorizationError

AccessDenied Error - extending the ServiceAuthorizationError error class

PublicMessage is set to 'Access denied' and the HttpCode is set to '403'.

Thrown when a users credentials does not match the requested endpoints credentials.

Extends: ServiceAuthorizationError

new AccessDenied(publicData, internalData)

hapiReply(replyOrResponseToolkit, [extraPublicData]) ⇒ Object

Reply function to respond with the error

Overrides: ServiceAuthorizationError#hapiReply Returns: Object - Response - Response object

x-imid-req-id

A unique id for the request. Used for debugging purposes.

Yes

x-imid-token

Contains the IMID token if INCLUDE_IMID_TOKEN_IN_REQUEST is set to true.

Yes

x-forwarded-for

Used for identifying the originating IP address of the client. If included in the request, the original value will be prepended to the final header.

No

x-forwarded-port

Used for identifying the port that the client used to connect. If included in the request, the original value will be used.

No

x-forwarded-proto

Used for identifying the protocol (HTTP or HTTPS) that the client used to connect. If included in the request, the original value will be used.

No

x-forwarded-host

Used for identifying the original host requested by the client. If included in the request, the original value will be used.

No

Param

Type

Description

publicData

Object

Required - Data to show in the error

internalData

Object

Required - Private data that can be logged in the error

Param

Type

Default

Description

replyOrResponseToolkit

Object

Required - Response toolkit - For example 'h' in Hapi, which handles the response

extraPublicData

Object

{}

Extra public data to shown in the error message

Param

Type

Description

publicData

Object

Required - Data to show in the error

internalData

Object

Required - Private data that can be logged in the error

Param

Type

Default

Description

replyOrResponseToolkit

Object

Required - Response toolkit - For example 'h' in Hapi, which handles the response

extraPublicData

Object

{}

Extra public data to shown in the error message

HttpTestServer

HttpTestServer{#HttpTestServer}

HttpTestServer{#HttpTestServer}

Http server to help the systemtest visualize http calls.

new HttpTestServer(params)

Param
Type
Description

start()

Start the http server.

Listening on specified port.

stop()

Stop the Http server.

Checks if there are any http calls left to respond to or endpoints waiting for calls, responds to these endpoints and then stops the server.

Throws errror if there are leftover calls not handled before shutdown.

getServerHost() {#getServerHost}⇒ string

Gets the server host.

Returns: string - networkInterfaceAddress - A string with the address for the eth0 network

waitForCall(endpoint, [params]) {#waitForCall}⇒ Promise.<Object>

Gets an endpoint to handle. Checks if an endpoint is waiting for an answer and resolves an answer to it.

Or puts the endpoint on a queue to be handled when a request for that endpoints comes in.

Returns: Promise.<Object> - Promise object represents the object with resolve, reject and params to resolve the incoming http call

Param
Type
Default
Description

onHttpCall(request, response) {#onHttpCall}⇒ Promise.<Object> | void

Handles all incoming Http calls

Either puts the request on queue to be handled or responds with data.

Returns: Promise.<Object> | void - Promise object represents an object with the data from the request or, returns void and puts the request in queue.

Param
Type
Description

ServiceAuthorizationError

ServiceAuthorizationError

new ServiceAuthorizationError(args)

hapiReply(replyOrResponseToolkit, [extraPublicData]) ⇒ Object

Reply function to respond with the error

Returns: Object - Response - Response object

Validate Access Tokens

When using IMSG

For services hosted behind an IMSG, nothing needs to be done. The IMSG does already support access tokens. The IMSG will take care of validating the access token and create a service token, just as if the API was accessed with an ID token.

Validate without IMSG

Authentication

Authentication means being sure of who the caller is

The steps required to ensure an access token is valid are the following:

  1. Ensure ntt (Naviga Token Type) claim in the access token payload equals access_token

  2. Read the kid (key id) from the access token header.

  3. Fetch the corresponding public key from for stage env or for production env.

It's important that server clock is synchronized, if not, the application might accept tokens that have expired.

The keys published on /jwkscan, and should, be cached for up to 10 min in the application.

Note, a token with a kid that does not exist in a cached /jwks might still be a valid token. It might be that a new key has been published but not yet fetched by the application. For that reason, the application should re-fetch the /jwks (once) if an unknown kid appears.

Similarly, a key might be revoked at any time, so never cache /jwks for more than 10min. If /jwks is cached for a longer period of time, tokens with invalidated kid/signature can appear to be valid when they are not.

Authorization

Authorization means knowing what actions the caller is allowed to do

Permissions are included as described by the payload below. Permission strings are on the format service_name:permission_name. Permissions in the permissions.org array should are valid in all units while permissions in permissions.units[unit_name] array is only valid in that specific unit.

More information about Naviga ID's permission model can be found on the page.

The Access Token payload is as follows:

Microsoft Azure

This document describes how to integrate Microsoft Azure using OpenID Connect with Naviga ID.

Prerequisites

The following steps in this document requires that you have a working Active Directory within Microsoft Azure. It can be a federation with a local Active Directory or your main Active Directory. Read more about how to Deploying Active Directory Federation Services in Azure

ExpressMiddleware

ExpressMiddleware{#ExpressMiddleware}

ServiceAuthorizationMiddleware{#ServiceAuthorizationMiddleware}

ServiceAuthorizationMiddleware

Imsg-service

/imsg-service/v1/callback

GET https://[SERVICE URL].com/imsg-service/v1/callback

Callback from IMAS login

Broken backwards compatibility in access token service for client credentials, 20th Dec 2021

All timestamps are in UTC

Summary

When a new release of the Naviga ID access token service was deployed to production on Dec 20th, it broke backwards compatibility for the scope parameter in the fetch token endpoint when using client credentials. Previously the scope parameter had been ignored, but in the new version it was not. This caused clients that set the scope parameter to anything other than an empty string to fail to fetch tokens.

Google G Suite

This document describes how to integrate Google G Suite using OpenID Connect with Naviga ID.

Prerequisites

The following steps in this document requires that you have a working G Suite directory .

params

Object

Required - The params object containing properties passed to the constructor

params.port

number

Required - Port number to start the Http server on

params.enableHealthEndpointAt

string

Required - Url string with the endpoint to the healthcheck

endpoint

string

Required - Url string with the endpoint to either resolve or put on a queue

params

Object

{}

Object with params to the request. Example: treatContentTypeAs: 'application/json'

request

Object

Required - Request object with the incoming http call

response

Object

Required - Response object to respond to the incoming http call

Param

Type

Default

Description

args

Object

Required - The args object passed to the constructor

args.publicData

Object

Required - Data to show in the error

args.internalData

Object

Required - Private data that can be logged in the error

args.publicMessage

string

"An error occurred"

Error message to be shown

args.httpCode

number

500

Http status code for error

Param

Type

Default

Description

replyOrResponseToolkit

Object

Required - Response toolkit - For example 'h' in Hapi, which handles the response

extraPublicData

Object

{}

Extra public data to shown in the error message

Service Integration

Query Parameters
Name
Type
Description

imid_token

string

IM ID JWT

serviceCallback

string

Where to redirect client after login

"Redirected to the service callback url"

/imsg-service/v1/health

GET https://[SERVICE URL].com/imsg-service/v1/health

Health status

{
  "inGrace": false,
  "stateChecksum": "A checksum string"
}
{
  "inGrace": false,
  "stateChecksum": "No checksum string"
}

/imsg-service/v1/login

GET https://[SERVICE URL].com/imsg-service/v1/login

Trigger login flow

Query Parameters

Name
Type
Description

callback*

string

Where to redirect client after login

org*

string

Which org to login with

/imsg-service/v1/token-is-set

GET https://[SERVICE URL].com/imsg-service/v1/token-is-set

Check if request contains IMID token

/imsg-service/v1/units

GET https://[SERVICE URL].com/imsg-service/v1/units

List all units a subject belongs to

/imsg-service/v1/org/{org}/login

GET https://[SERVICE URL].com/imsg-service/v1/org/{org}/login

Trigger login flow

Query Parameters

Name
Type
Description

callback*

string

Where to redirect client after login

/imsg-service/v1/logout

POST https://[SERVICE URL].com/imsg-service/v1/logout

Log out

Query Parameters

Name
Type
Description

callback

string

Where to redirect client after logout

/imsg-service/v1/unit

POST https://[SERVICE URL].com/imsg-service/v1/unit

Set preferred unit

Request Body

Name
Type
Description

unit

string

Preferred unit

Ensure alg (algorithm) in the access token header is identical to the key's alg

  • Use a suitable library for your language to validate the access-token signature using the key

  • Check that current time is less than exp in access token payload.

  • https://imas.stage.imid.infomaker.io/v1/jwks
    https://imas.imid.infomaker.io/v1/jwks
    authorization schema
    "Redirected after login"
    {
      "msg": "ok"
    }
    "errors.auth.MissingToken"
    {
      "msg": "Unit set"
    }
    "errors.auth.Forbidden"
    "Redirected after login"
    {
      "msg": "You are logged out"
    }
    {
      "msg": "Unit set"
    }
    "errors.auth.Forbidden"
    { 
      "ntt": "access_token", // ntt stands for Naviga Token Type
      "org": string, // org name
      "sub": uuid_string, // subject is the unique user id in Naviga ID
      "groups": [string, string,...], // groups the sub belongs to in the organization's identitity provider
      "userinfo": { 
        "given_name": string, // optional
        "family_name": string,  // optional
        "email": string, // optional
        "picture": string // optional
      },
      "permissions": {
        "org": [string, string,...] // permissions valid in all units,
        "units": {
          unit_string_name : [string, string...], // permissions only valid in unit unit_string_name
          ...
        } 
      } 
      "iat": unix_timestamp_seconds, // issued at
      "exp": unix_timestamp_seconds,  // expires at
      "jti": uuid_string, // token id
    } 
    Setting up an Azure Active Directory app to work with Naviga Login
    1. Login to https://portal.azure.com/ and click on Azure Active Directory and the on App registrations (Preview)

    2. Click on New registration

      • Name: <Your choice of name> Proposal: Naviga Login

      • Supported account types: Accounts in this organizational directory only (Standardkatalog)

      • Redirect URI (optional): Web /

    3. Go to Authentication within your new created app and then following URLs under Redirect URIs as Web types (organization name will be provide to you by Infomaker/Newscycle):

      https://imas.stage.imid.infomaker.io/v1/org/<OrganizationName>/login-callback

      https://imas.imid.infomaker.io/v1/org/<OrganizationName>/login-callback

    4. Go to API permissions and enable the following:

      • openid

      • email

      • offline_access

    You can read more about user permissions and OpenId in the Azure documentation.

    1. Go to Certificates & secrets and add a new Client secret

      • Description: client_secret

      • Expires: Your choice. But remember that you need to provide Naviga with a new Client Secret before the expiry date runs out otherwise your users will not be able to login with Naviga ID after the expiry date.

    2. Copy the Value and keep it in a safe place. The value will be gone after you leave that page.

    3. Go to Manifest and replace the following items:

    This will include user groups in tokens

    This will include given name and last name in tokens

    You are now done with configuration

    Add permissions for Naviga ID to read group names

    By default, Azure AD only provides group IDs in the token and in order for Naviga ID to fetch the names of those groups, additional configuration is required.

    Under API permissions add the following delegated permission:

    • GroupMember.Read.All

    This allows Naviga ID to list groups, read basic group properties and read membership of all groups the signed-in user has access to.

    Gather The Required Information and Speak With Your Naviga Contact

    The infomartion needed by Naviga to complete the integration

    • Application (client) ID for you app Example: 582fca63-a083-41f2-b8d2-0d35e3acf16f

    • Client secret for your app

    • The URL for OpenID Connect metadata document Example:

    • Create at least two accounts for Naviga. One for a regular user and one for a admin user (example [email protected] and [email protected]). This users should also be assigned to groups within Azure AD

    https://docs.microsoft.com/en-us/windows-server/identity/ad-fs/deployment/how-to-connect-fed-azure-adfs

    new ServiceAuthorizationMiddleware(options)

    Param
    Type
    Description

    options

    Object

    Required -

    options.serviceTokenSignSecret

    string

    Required - Secret to validate token signature against

    authorize(authParams)

    Extract and authorize token using the provided auth params

    Param
    Type
    Description

    authParams

    FullAuthorizationParameters | AuthorizationMode

    Required - Authorization parameters to pass to

    errorHandler([err], req, res, next)

    Error handler for errors thrown by ServiceAuthorizationMiddleware

    Will handle telling IMSG to redirect unauthorized requests, but will pass on any other errors to next()

    Param
    Type
    Description

    err

    Object

    Express err

    req

    Object

    Required - Express req

    res

    Object

    Required - Express res

    The type definition of the full auhtorization object with all parameters.

    Passed to the authorize function.

    Properties

    Name
    Type
    Description

    onPreAuth

    function

    Function to run before authorize is called

    org

    string | function | Boolean

    Required - Organiztion to authorize against

    accessRules

    Array.<AccessRule>

    Optional access rules to authorize against

    The type definition of the access rule.

    Passed to the authorize function within the object as a list of access rules.

    All properties are optional, but at least one must exist

    Properties

    Name
    Type
    Description

    unit

    string | function

    Unit that should match token

    permission

    string | function

    Permission that should match token

    sub

    string | function

    Subject that should match token

    Type defintion of the authorization mode.

    SERVICE_ADMIN_ENDPOINT - Authorization validates if you are a service admin and have a valid token. Either accessed or thrown out.

    OPEN_ENDPOINT - Authorization validates if you have a valid token and lets you through to the open endpoint. Either accessed or thrown out.

    Either SERVICE_ADMIN_ENDPOINT or OPEN_ENDPOINT

    Impact

    The bug was present between 12:43 and 16:39 on December 20th 2021. During this time, only two applications belonging to the one customer are known to have experienced the issue. For the customer, this meant that one import flow and one export flow stopped working. The customer received workaround instructions at 15:24. Around one hour later, the problem was resolved when a fix was deployed to the access token service.

    Background

    Naviga ID supports applications to authenticate themselves using client credentials. In return, an access token is sent that can be used to access Naviga's content creation services. One common use case is import and export applications.

    The HTTP endpoint for fetching access tokens is designed to be compatible with the OAuth 2 standard. Apart from the credentials (client_id and client_secret), a parameter named scope is also defined the standard. Up until 12:43 on Dec 20th, the scope parameter had been allowed to be set, but its value had been ignored and carried no functionality. The reason for allowing scope to be set (even though not being in use) was to support tools and libraries that might default to set scope to an empty string unless otherwise configured.

    Setting an empty scope variable was both supported and tested in Naviga ID. And, while it was also supported to set it to any string value, there were no test cases implemented for that scenario.

    On Dec 20th, support for a new type of scope-based applications were added to Naviga ID. These new applications make use of the scope variable when fetching access tokens. Erroneously, the presence of a non empty string value in the scope parameter was used as an identifier for these new scope-based applications. When the system tried to handle a legacy application as a scope-based application, an internal error was triggered and a 500 HTTP error was returned. Because no test-case for this scenario existed for legacy applications, the problem was not identified during development.

    Before the bug was fixed, one customer was identified that had two applications where the scope value was set to the string value "basic". A workaround for the customer was to remove the scope value. The fix in the access token service was to restore the previous behavior of ignoring the scope parameter for legacy applications.

    Timeline

    Time
    Time since last event
    Event

    December 10th, 12:02

    -

    Scope-based application support deployed to Naviga ID Stage. Backwards compatibility broken.

    December 20th, 12:43

    10 days

    Scope-based application support deployed to Naviga ID Production. Backwards compatibility broken.

    December 20th, 12:44

    1min

    Elevated 500 error levels but no alarm triggered

    Actions

    Other learnings

    • Stage environments are not used in similar enough fashion to prod environments. Had they been, this issue would have been found and fixed before reaching production systems.

    • In future feature development, implement stricter validation from the beginning. Fail fast and early. Catching all backwards compatibility scenarios gets a lot trickier when looser validation is implemented.

    • The impact of issues might seem greater than they are when triggered by one or two traffic intensive clients.

    Generate a Client ID and Client Secret

    1. Login to your Google account and go to the API Manager

    2. Click on Select a project dropdown and choose that project you want to use or create a new one.

    3. Click on Create credentials and select the OAuth client ID

    4. Google show a banner saying "To create an OAuth client ID, you must first set a product name on the consent screen". Click on Configure consent screen

    5. Type the Product Name that will be shown to the users when they log in through GSuite, add infomaker.io as an Authorised domain and click Save.

    6. Now we will fill in information about the app. Start with selecting Web application and provide a name for your app.

    8. Under Restrictions, fill in following information:

    • Authorized JavaScript origins: https://imas.imid.infomaker.io, https://imas.stage.imid.infomaker.io

    • Authorized redirect URI: https://imas.stage.imid.infomaker.io/v1/org/<OrganizationName>/login-callback, https://imas.imid.infomaker.io/v1/org/<OrganizationName>/login-callback

    <OrganizationName> should be replaced with a name given to you by Naviga.

    9. Click on Create and your Client ID and Client Secret will now be displayed.

    Enable the API access

    1. From the Admin console Home page, go to Security > API reference.

    2. Check the Enable API access box.

    3. Click save.

    Enable Admin SDK

    1. Go to https://console.developers.google.com/apis/library

    2. Search for Admin SDK

    3. Click on Admin SDK and click on Enable

    Create a Service Account for Fetching User Groups

    If you want Naviga Login to be able to fetch groups for the logged in user, a service account is required.

    Create a service account and delegate domain-wide authority to it by following this guide: https://developers.google.com/admin-sdk/directory/v1/guides/delegation.

    The following scopes are required to fetch user groups: https://www.googleapis.com/auth/admin.directory.group.readonly

    Access to the G Suite Admin SDK requires impersonating a user with access to the Directory API:

    Note: Only users with access to the Admin APIs can access the Admin SDK Directory API, therefore your service account needs to impersonate one of those users to access the Admin SDK Directory API. Additionally, the user must have logged in at least once and accepted the G Suite Terms of Service.

    Gather The Required Information and Speak With Your Naviga Contact

    The information needed by Naviga to complete the integration

    • URL to your OpenID provider metadata file (.well-known/openid-configuration)

    • Client ID

    • Client secret

    • Private key file of the created service admin in JSON format

    • Email address or user ID of a user with access to the Directory API

    • Domain for which to retrieve the user groups

    https://gsuite.google.com/

    Release notes

    Access Token: 2.5.0

    2022-09-09

    • Add scopes to filter access token permissions

      • permission-filter-include-org

      • permission-filter-include-unit:{unitName}

    See for details.

    IMSG: 17.8.3

    2022-09-09

    • Upgrade internal dependencies

    IMSG: 17.8.2

    2022-06-28

    • Upgrade internal dependencies

    Access Token: 2.4.2

    2022-06-28

    • Upgrade internal dependencies

    IMSG: 17.8.1

    2022-06-22

    • Upgrade internal dependencies

    Access Token: 2.4.1

    2022-06-22

    • Upgrade internal dependencies

    Access Token: 2.4.0

    2022-06-16

    • Wildcard unit scope puts permissions into units if not allowed in org

    Consider the following permissions:

    Before this update, requesting a token with scope permission:*:writer:access would result in an error since writer:access is not present in the org permissions.

    Now, requesting the same scope will result in the following permissions:

    Access Token: 2.3.0

    2022-04-28

    • Cache private keys to avoid exceeding SSM limit

    IMSG: 17.8.0

    2022-03-28

    • Default to less strict validation of cookie payload

    Hapi, the web server framework used by IMSG, defaults to a strict validation of cookies according to rfc6265 (). This includes not allowing raw JSON as the cookie value. With this change, a less strict validation of cookies will be the default behaviour.

    This will solve issues caused by other services setting cookies on or that do not adhere to rfc6265. The less strict validation is the default behaviour of most other servers as well as all major browsers.

    Environment variable changes

    This can be overridden by setting env variable STRICT_COOKIE_MODE to true.

    IMSG: 17.7.1

    2022-03-28

    • Internal maintenance

    IMSG: 17.7.0

    2022-03-28

    • For access tokens, use the permissions claim in the token instead of resolving permissions based on groups

    There are two different kind of tokens in Naviga ID that can be used to access services behind an IMSG reverse proxy.

    When you log in to CCT in the browser, an ID token (sometimes called session token) is stored as a cookie in your browser. This token does not hold any permissions. Instead, the groups that you belong to are stored in the token. When you access a CCT service, the IMSG will translate the groups into permissions (based on the current latest organization configuration). The permissions are then forwarded to the service.

    The second type of token is access tokens. Access-tokens are fetched from the access token service using either an ID-token or client credentials. When an access token is created, it is populated with the resolved permissions from the start. Hence there’s no need for IMSG to try to resolve them again.

    Up until this release, IMSG ignored any permission claim the access tokens and only used the list of groups to resolve the permissions. With this change in place, IMSG will always use the permissions claim in access tokens and forward those permissions to the service.

    IMSG: 17.6.1

    2021-05-07

    • Internal maintenance release. No changes to service.

    IMSG: 17.6.0

    2021-05-07

    • Upgrade of Node from 10 to 14.

    • Upgrade of dependencies

    Access Token: 1.4.0

    2021-03-01

    • Access tokens obtained through client credentials are now counted as internal access in the billing API

    IMSG: 17.5.1

    2021-02-04

    • Bugfix: validate IMSG service callback against correct cookie domain when using full URL in service callback

    IMSG: 17.5.0

    2021-01-29

    Support for allowing any headers during CORS requests

    IMSG can now allow any headers in CORS requests. Enabling this feature reflect the value of access-control-request-headers into the response access-control-allow-headers. Use with care.

    Environment variable changes

    CORS_ALLOW_ANY_HEADERS has been added. Set to true to enable.

    IMSG: 17.4.0

    2021-01-20

    Support for multiple domains

    IMSG can now serve and set cookies on multiple domains. To enable multiple domains, set the IMID_COOKIE_DOMAINS environment variable to the domains you want to access IMSG on.

    ex. IMID_COOKIE_DOMAINS="infomaker.io, navigacloud.com"

    Environment variable changes

    IMID_COOKIE_DOMAIN has changed name to IMID_COOKIE_DOMAINS and changed type from sting to CSV. The legacy name will continue to be supported.

    IMSG: 17.3.0

    2020-12-17

    Legacy mode feature flag for units

    IMSG now supports a legacy mode where only units with explicit permission mappings are included in the service token. This is required for the current version of the unit-selector (in writer and dashboard) to function properly. To enable legacy mode, set the "short-and-to-the-point" env variable LEGACY_MODE_ONLY_INCLUDE_UNITS_WITH_EXPLICITLY_MAPPED_PERMISSIONS_IN_SERVICE_TOKEN to true.

    Security fix

    The redirect option in the /callback endpoint now only accepts full URLs if the URL is hosted under the cookie domain env variable ( or )

    Preparations for improved refresh flow

    IMSG now supports the rta (refresh token after) claim which soon will be included in all ID-tokens (browser cookie tokens). The rta claim is the future way to centrally control when refresh is to be performed. Refresh backoff support. In certain situations when an IMSG is unable to refresh a token after rta has passed, or if IMAS responds with a 429 status code during refresh, IMSG will backoff and not try to refresh the token for a given time period. The other parts of the new refresh flow is implemented in IMAS and will be deployed starting January 2021. The changes will be rolled out in three steps, as described below.

    1. The ID-token's exp (expiry) claim will be increased to several days (from today's 1h). This means that as long as the user is logged in to Naviga ID, they will continue to be so even if their organization's IdProvider goes down. This would for example have minimized the impact of Google's outage the other day quite a bit.

    2. Refresh of ID-tokens will be limited to once per token. This is the current expected behavior, so there won't be any impacts for users in all normal scenarios. However, in the event that an ID-token is stolen from a user, we can identify that if more than one refresh is triggered. In the initial roll out, the only action taken is to log and alarm. When we are confident we have no false-positives, we'll deploy step 3.

    3. If a token is used for refresh more than once, we will invalidate all issued tokens for that user. This will lead to both the legitimate user and the intruder to be logged out from Naviga ID. The legitimate user will be able log in again while the intruder no longer has access.

    Access Token: 1.3.0

    2020-12-15

    • Internal access tokens now have an ntt claim of internal_access_token

    Access Token: 1.2.0

    2020-10-12

    • Cache client credentials

    Admin App: 1.2.0

    2020-10-12

    • Make deploy environment configurable via environment variable

    IMSG: 17.2.0

    2020-09-11

    • Pre-expire refresh of tokens. Tokens will now be refreshed around 10 minutes before they expire.

    • New /v1/units endpoint to fetch all units a user belongs to. The response contains the unit display names.

    IMSG 17.2.1 (2020-10-12)

    • IMSG now handles userinfo from access tokens correctly, fixing a bug where service tokens would contain no userinfo

    Admin App 1.1.0

    2020-09-11

    • Add missing config options for Azure LFE

      • useFullGroupsEndpoint

      • useTransitiveGroupMemberships

    Admin API 19.2.0

    2020-09-11

    • Two new endpoints for import/export of organization units and group mappings. See for details.

      • GET /v1/organizations.export

      • POST /v1/organizations.import

    Admin API 19.2.1 (2020-10-12)

    • Fix bug where only admins could create credentials for organization applications

    IMSG 17.1.0

    2020-08-21

    • All organization units are now included in the service token whether the user has any permissions in it or not. Units the user does not belong to will have no permissions in it.

    IMSG 17.1.1 (2020-08-21)

    • Dependency upgrades

    IMSG 17.0.0

    2020-05-07

    • Remove old M2M support

    IMSG 17.0.1 (2020-05-12)

    • Dependency downgrades

    SAL 5.6.0

    2020-03-02

    • No longer requires environment variables IM_LOG_LEVEL and IM_LOG_NAME.

    • Log level will default to info and log name to Log name not set

    IMSG 16.8.0

    2020-03-02

    • No longer counts internal users towards billable users

    • Subjects with the first name Naviga will be tagged as internal access.

    IMSG 16.7.0

    2020-03-02

    • New env variables ONLY_ACCEPT_ID_TOKENS, INCLUDE_GROUPS_IN_SERVICE_TOKEN

    • New login url /v1/login with org and callback as query params

    Internal applications

    /internalApplications.get

    GET https://admin-api.imid.infomaker.io/v1/internalApplications.get

    Get internal application

    Query Parameters

    Name
    Type
    Description

    /internalApplications.list

    GET https://admin-api.imid.infomaker.io/v1/internalApplications.list

    List internal applications

    Path Parameters

    Name
    Type
    Description

    /internalApplications.create

    POST https://admin-api.imid.infomaker.io/v1/internalApplications.create

    Create internal application

    Request Body

    Name
    Type
    Description

    /internalApplications.createCredential

    POST https://admin-api.imid.infomaker.io/v1/internalApplications.createCredential

    Create internal application credentials

    Request Body

    Name
    Type
    Description

    /internalApplications.delete

    POST https://admin-api.imid.infomaker.io/v1/internalApplications.delete

    Delete internal application

    Request Body

    Name
    Type
    Description

    /internalApplications.deleteCredential

    POST https://admin-api.imid.infomaker.io/v1/internalApplications.deleteCredential

    Delete internal application credential

    Request Body

    Name
    Type
    Description

    /internalApplications.modify

    POST https://admin-api.imid.infomaker.io/v1/internalApplications.modify

    Modify internal application

    Request Body

    Name
    Type
    Description

    Permissions

    /permissions.get

    GET https://admin-api.imid.infomaker.io/v1/permissions.get

    Get permission by id

    Query Parameters

    Name
    Type
    Description

    /permissions.list

    GET https://admin-api.imid.infomaker.io/v1/permissions.list

    List permissions

    Path Parameters

    Name
    Type
    Description

    /permissions.create

    POST https://admin-api.imid.infomaker.io/v1/permissions.create

    Create permission

    Request Body

    Name
    Type
    Description

    /permissions.delete

    POST https://admin-api.imid.infomaker.io/v1/permissions.delete

    Delete permission by id

    Request Body

    Name
    Type
    Description

    /permissions.setDescription

    POST https://admin-api.imid.infomaker.io/v1/permissions.setDescription

    Set permission description by id

    Request Body

    Name
    Type
    Description

    /permissions.setName

    POST https://admin-api.imid.infomaker.io/v1/permissions.setName

    Set permission name by id

    Request Body

    Name
    Type
    Description

    Errors

    Errors{#Errors}

    ServiceAuthorizationError{#ServiceAuthorizationError}⇐ Error

    ServiceAuthorizationError - extending the Error class.

    Base class for each kind of errors in ServiceAuthorizationLib.

    Extends: Error

    new ServiceAuthorizationError(args)

    Param
    Type
    Default
    Description

    hapiReply(replyOrResponseToolkit, [extraPublicData]) {#hapiReply}⇒ Object

    Reply function to respond with the error

    Returns: Object - Response - Response object

    Param
    Type
    Default
    Description

    AccessDenied{#AccessDenied}⇐ ServiceAuthorizationError

    AccessDenied Error - extending the ServiceAuthorizationError error class

    PublicMessage is set to 'Access denied' and the HttpCode is set to '403'.

    Thrown when a users credentials does not match the requested endpoints credentials.

    Extends: ServiceAuthorizationError

    new AccessDenied(publicData, internalData)

    Param
    Type
    Description

    Unauthorized{#Unauthorized}⇐ ServiceAuthorizationError

    Unauthorized - extending the ServiceAuthorizationError error class

    PublicMessage is set to 'Unauthorized' and the HttpCode is set to '401'.

    Thrown when a user tries to request an endpoint with no access to it.

    Extends: ServiceAuthorizationError

    new Unauthorized(publicData, internalData)

    Param
    Type
    Description

    ConfigError{#ConfigError}⇐ ServiceAuthorizationError

    ConfigError - extending the ServiceAuthorizationError error class

    PublicMessage is set to 'Internal Server Error' and the HttpCode is set to '500'.

    Thrown when building config variables while authorize.

    Extends: ServiceAuthorizationError

    new ConfigError(publicData, internalData)

    Param
    Type
    Description

    Authorize

    Authorize{#Authorize}

    authorize(params) {#authorize}⇒ authorizationSuccessResult | authorizationErrorResult

    Main authorization function

    Consists of the following steps:

    1. If token is missing and endpoint is open, authorize request.

    2. Validate and decode service token.

    3. If servieToken exists and endpoint is open, authorize request.

    4. Try to authorize using serviceAdmin.

    Returns: authorizationSuccessResult | authorizationErrorResult - Either returns an authorizeSuccessResult object or an authorizationErrorResult object

    Param
    Type
    Description

    The result object returnd if the authorization was successful

    Param
    Type
    Description

    The error object returned if the authorization failed.

    Returns either Unauthoried, AccessDenied or ConfigError

    Param
    Type
    Description

    TokenUtils

    TokenUtils{#TokenUtils}

    Module with helper functions for the Tokens.

    extractServiceTokenFromRequest(request) {#extractServiceTokenFromRequest}⇒ Object

    Extracts and decodes a service token from a raw request

    Returns: Object - serviceToken - The service token

    Param
    Type

    extractImidTokenFromRequest(request) {#extractImidTokenFromRequest}⇒ String | null

    Extracts IMID token from a raw request if present

    Returns: String | null - imidToken - The IMID token if present

    Param
    Type

    getSubject(request) {#getSubject}⇒ String

    Get the subject from the service token

    Returns: String - organization - The subject identifier set on the service token

    Param
    Type

    getOrganization(request) {#getOrganization}⇒ String

    Get the subject's organization

    Returns: String - organization - The organization the subject belongs to

    Param
    Type

    getUnits(request) {#getUnits}⇒ Array.<String>

    Get the subject's mapped units

    Returns: Array.<String> - units - An array of all units the subject belongs to

    Param
    Type

    getSelectedUnit(request) {#getSelectedUnit}⇒ null | String

    Get the subject's selected unit

    Returns: null | String - unit - The subject's selected unit, null if no unit selected

    Param
    Type

    getOrgPermissions(request) {#getOrgPermissions}⇒ Array.<String>

    Get the subject's organization permissions

    Organization permissions are located under permissions.org

    Returns: Array.<String> - } permissions - The subject's org permissions

    Param
    Type

    getUnitPermissions(request, unit) {#getUnitPermissions}⇒ Array.<String>

    Get the subject's permissions for the specified unit

    Unit permissions are located under permissions.units[unit]

    Returns: Array.<String> - permissions - The subject's permissions for the specified unit

    Param
    Type
    Description

    isServiceAdmin(request) {#isServiceAdmin}⇒ Boolean

    Checks if a token belogs to an admin for the service

    Returns: Boolean - isServiceAdmin - True if the token belongs to an admin for the service

    Param
    Type

    getUserinfo(request) {#getUserinfo}⇒ Object

    Get the subject's userinfo

    Returns: Object - userinfo - The userinfo object set on the subject

    Param
    Type

    Managing Applications

    Organizational applications represents customer applications that need to authenticate on their own behalf to perform actions using Naviga Content tools and APIs. Common use cases are machine to machine operations such as import or export of content to and from CCA and OC.

    Organizational applications identify themselves using client credentials, which consists of client_id and client_secret, comparable to username and password. The client credentials are used to fetch an access token, which in turn is used for authentication when accessing Naviga Content tools and APIs. Both client credentials and access tokens are part of the OAuth2 specification.

    This page describes how to create and manage organizational applications and related credentials in Naviga ID. For instructions on how to actually use client credentials to fetch access tokens and access APIs, see Fetching and using Access Tokens.

    Creating an application

    As of December 2021, the Admin App that is used to manage Naviga ID configuration does not yet support managing applications and client credentials. However, the Admin API does support all required operations.

    The full API for managing applications and credentials are available at the .

    To create applications, the role imid:admin is required. Auth can be either an ID-Token or Access-Token, either as cookie or in the Authorization HTTP header as Bearer token.

    To create an application, you'll need the organization id, not the name. The organization id can be seen in the URL when configuring an organization in the Admin App at https://admin.stage.imid.infomaker.io

    There are two ways to define the permissions an application should have. The legacy way by using groups, and the recommended way of using scopes.

    Specifying permissions using scopes

    Scopes are simply string representations of roles and permissions that includes information if the role or permission is valid in a specific unit or the entire organization.

    By using scopes to define what an application is allowed to do, all "group-to-role" mappings in Naviga ID are bypassed. So instead of using an intermediate format and config, the roles and permission that an application are allowed to assume is defined directly in the application itself on creation (can be updated).

    Another benefit with scopes is that they are also used when fetching access tokens. This enables fetching of tokens with a subset of the permissions an application is allowed to assume which greatly limits the implications if an access-token would be shared or leaked. To learn more about this, go to the page.

    All scopes have the following format

    ["permission"|"role"]:[unitName|"*"]:[serviceName]:[entityName]

    Below are example of the allowed type of scopes when creating applications

    Example scope
    Description

    To use multiple scopes, simply create a space separated list of them as the example below.

    To create an application, you'll need the organization Id, the name you want to give the application, a description as well as the scopes that you wish to give the application.

    To create an application, use the /v1/organizationApplications.create in the Admin API. The scopes that define roles and permissions that the applicatin can assume should be entered in the allowedScopes payload parameter. See the .

    In the response you'll get the id of the application (client_id) as well as one initialclient_secret that you'll need to . To enable easy rotation of secrets, Naviga ID supports multiple client_secret per application. For more details, see the lower down on this page.

    Specifying permissions using groups

    This method is no longer recommended. Instead, please use scopes as described in the step. With scopes, the application owns the configuration and can also fetch access-tokens that only hold a subset of permissions that an application is allowed to take.

    To create an application with permissions based on groups, you'll first need the organization Id, the name you want to give the application, a description as well as the groups that you wish the application to belong to. The groups you define will be used to map roles/units according to the organization's configuration in Admin App.

    To create an application, use the /v1/organizationApplications.create in the Admin API. See the .

    In the response you'll get the id of the application (client_id) as well as one initialclient_secret that you'll need to . Naviga ID supports multiple client_secret per application, to enable easy rotation of secrets. For more details, see the lower down on this page..

    Rotation of credentials (client_secret)

    Credentials can, and should be rotated in defined intervals for security reasons.

    To enable easy rotation of client_secret, Naviga ID Organizational Applications support multiple credentials. That way, it's possible to rotate credential with zero downtime in services by creating a new credential for the application and updating all places where the old credential is used before removing it from Naviga ID.

    See the Admin API documentation on for details on how to find the id of the current credential, create a new credential and delete the old credential.

    Use client credentials to access Naviga Services

    See .

    Local HTTPS support

    How to enable local development with HTTPS support

    Naviga ID does not allow the ID-token cookie to be included in requests over unencrypted connections. Therefore, local SSL support is required to have locally hosted web applications make use of the Naviga ID cookie.

    For this to work, a couple of things are needed

    • A locally running HTTP service

    • A locally installed root-certificate that can be used to generate custom certificates

    • A local proxy that handles the SSL handshake and encryption/decryption and also proxy the request to the local HTTP service

    • At least one ...local.infomaker.io entry in /etc/hosts that points to 127.0.0.1

    Almost all web backends support SSL termination. However, since we always use ALB, API Gateway, or CloudFront for SSL termination in our hosted services, it's better to mimic that setup with a proxy locally as well. That way, no code change is required for your service.

    Let's get started!

    1. Start a demo http-server

    For simplicity and to ensure that anyone can use this guide, a simple demo server is used instead of an actual Naviga service. At the end of the guide, there's a description of what you need to change to run one (or more) "real" services locally with HTTPS support.

    To start the demo server, open a terminal and run the following command

    Let the application run and open your browser and verify that returns a test page.

    Looks good? Great!

    2. Install and run mkcert

    Next, let's install the tool that will help us generate and install root and service certificates. Go to and follow the installation instructions for your OS.

    Once installed, execute the following steps to generate your first certificate.

    3. Install and configure Caddy as reversed proxy

    The next step is to install the proxy server to use for the SSL termination. Go to and follow the instructions for your OS.

    Next, create a file called ~/Caddyfile in your home directory. Use the example below as a template but make sure to replace the name in the path to the certificates (/home/jacob/certificates/...) with the name of your home dir.

    There are two instances on line 3 where the name must be replaced

    Once done, run the following commands

    4. Configure /etc/hosts to map domain name to localhost

    The last step to tie it all together is to update your local hosts file with an entry that tells your browsers and applications that demo.local.infomaker.io is hosted on your own machine and not online somewhere. We use the same domain name as in the ~/Caddyfile and add it to /etc/hosts as below

    5. Profit!

    If you open your browser and go to you should be greeted with the same test page as before, but this time with a locked padlock to the left or the URL bar and no errors about an unsecured connection.

    6. Optional: Run multiple services

    To add more services, simply duplicate the current entry in the ~/Caddyfile and update the following parts:

    1. The domain name. Change demo to whatever name you want to use for your service

    2. The local port. Change localhost:8888 to match the port your application is bound to.

    Save the file and reload the Caddy config

    Finally, add an entry in /etc/hosts that matches the domain you added in ~/Caddyfile

    Gotchas

    Some frameworks (such as Node) have their own trust-store. In that case, the root certificate must be added there as well. If not added, any requests from node to will fail since the root certificate from mkcert is not trusted.

    For node, make sure you have the following environment variable set.

    If you're using Docker, you must also mount the rootCA.pem file inside docker, and use the NODE_EXTRA_CA_CERTS to point the location inside docker.

    Services

    /services.get

    GET https://admin-api.imid.infomaker.io/v1/services.get

    Get service by id

    "groupMembershipClaims": "All"
    "optionalClaims": {
        "idToken": [
            {
                "name": "given_name",
                "source": null,
                "essential": false,
                "additionalProperties": []
            },
            {
                "name": "family_name",
                "source": null,
                "essential": false,
                "additionalProperties": []
            }
        ],
        "accessToken": [],
        "saml2Token": []
    },

    next

    function

    Required - Express next

    suppressLoginTrigger

    Boolean

    If true, do not redirect failed authorization to login

    December 20th, 15:01

    2h, 17min

    Customer reports issues with APIs in Slack

    December 20th, 15:03

    2min

    First response by Naviga personnel

    December 20th, 15:08

    5min

    Naviga ID developers notified about the issue. Unfortunately, both developers had clocked out and were not located right by a computer

    December 20th, 15:20

    12min

    Naviga ID developer online and root cause identified

    December 20th, 15:24

    4min

    Customer informed of workaround (remove scope from request)

    December 20th, 15:30

    6min

    Workaround confirm to work by customer

    December 20th, 16:29

    59min

    Fix released and verified in stage.

    December 20th, 16:39

    10min

    Fix released and verified in prod.

    request

    http.IncomingMessage

    request

    http.IncomingMessage

    request

    http.IncomingMessage

    request

    http.IncomingMessage

    request

    http.IncomingMessage

    request

    http.IncomingMessage

    request

    http.IncomingMessage

    request

    http.IncomingMessage

    Required -

    unit

    String

    Required - The unit permissions should be checked in

    request

    http.IncomingMessage

    request

    http.IncomingMessage

    Required - Private data that can be logged in the error

    args.publicMessage

    string

    "An error occurred"

    Error message to be shown

    args.httpCode

    number

    500

    Http status code for error

    args

    Object

    Required - The args object passed to the constructor

    args.publicData

    Object

    Required - Data to show in the error

    args.internalData

    replyOrResponseToolkit

    Object

    Required - Response toolkit - For example 'h' in Hapi, which handles the response

    extraPublicData

    Object

    {}

    Extra public data to shown in the error message

    publicData

    Object

    Required - Data to show in the error

    internalData

    Object

    Required - Private data that can be logged in the error

    publicData

    Object

    Required - Data to show in the error

    internalData

    Object

    Required - Private data that can be logged in the error

    publicData

    Object

    Required - Data to show in the error

    internalData

    Object

    Required - Private data that can be logged in the error

    Object

    Build auth params and check if service token exists.

  • Authorize organization.

  • Authorize using optional accessRules.

  • string

    Required - The secret the unverified token should be validated with

    params.request

    Object

    Required - The request object to be made availbable in authParams

    Object

    Required -

    result.artifacts.reason

    string

    Required - Why the request was authorized

    result.artifacts.authenticationParameters

    Array.<Object>

    Required - The built authorization parameters used to authorize the request

    result.artifacts.matchingAccessRules

    Array.<Object>

    Required - The built access rules that matched the provided token

    result.artifacts.matchingServiceAdmin

    Object

    Required - If the token matched a service admin rule

    params

    Object

    Required -

    params.authParams

    AccessRule

    Required - Object with auth parameters from the request

    params.unverifiedServiceToken

    string

    Required - Unverified service token in JWT format

    result

    Object

    Required -

    result.credentials

    Object

    Required -

    result.credentials.serviceToken

    Object

    Required - Decoded service token used to authorize the request

    result

    Object

    Required -

    result.err

    ErrorsUnauthorized | ErrorsAccessDenied | Errors~ConfigError

    Required - The error thrown during authorization

    params.serviceTokenSignSecret

    result.artifacts

    Query Parameters
    Name
    Type
    Description

    serviceId

    string

    Service id

    {
      "id": "Service id",
      "name": "dashboard",
      "description": "Description of speicific part xxx",
      "updatedBySub": "infomaker_b8b9373b-a30d-459d-a44d-f270afb5e581"
    }
    "errors.api.BadRequestError"
    "errors.api.InternalServerError"

    /services.list

    GET https://admin-api.imid.infomaker.io/v1/services.list

    List services

    Path Parameters

    Name
    Type
    Description

    string

    /services.create

    POST https://admin-api.imid.infomaker.io/v1/services.create

    Create service

    Request Body

    Name
    Type
    Description

    name

    string

    Infomaker service name

    description

    string

    Description of speicific part xxx

    /services.delete

    POST https://admin-api.imid.infomaker.io/v1/services.delete

    Delete service by id

    Request Body

    Name
    Type
    Description

    serviceId

    string

    Service id

    /services.setDescription

    POST https://admin-api.imid.infomaker.io/v1/services.setDescription

    Set service description by id

    Request Body

    Name
    Type
    Description

    serviceId

    string

    Service id

    description

    string

    Description of speicific part xxx

    /services.setName

    POST https://admin-api.imid.infomaker.io/v1/services.setName

    Set service name by id

    Request Body

    Name
    Type
    Description

    serviceId

    string

    Service id

    name

    string

    Infomaker service name

    Do not allow refresh when using access_token
  • Include exp in service-token

  • Add naviga_admin as second service admin org

  • access token documentation
    https://datatracker.ietf.org/doc/html/rfc6265
    infomaker.io
    navigacloud.com
    infomaker.io
    navigacloud.com
    Admin API docs

    internalApplicationId

    string

    Internal application ID

    string

    serviceId

    string

    Service id

    name

    string

    Internal application name

    description

    string

    Description of speicific part xxx

    internalApplicationId

    string

    Internal application ID

    internalApplicationId

    string

    Internal application ID

    internalApplicationId

    string

    Internal application ID

    internalClientCredentialId

    string

    Internal application credential ID

    internalApplicationId

    string

    Internal application ID

    name

    string

    Internal application name

    description

    string

    Description of speicific part xxx

    {
      "id": "Internal application ID",
      "serviceId": "Service id",
      "name": "my-internal-application",
      "description": "Description of speicific part xxx"
    }
    "errors.api.BadRequestError"
    "errors.api.InternalServerError"

    permissionId

    string

    Permission id

    string

    serviceId

    string

    Service id

    name

    string

    Service permission name

    description

    string

    Description of speicific part xxx

    permissionId

    string

    Permission id

    permissionId

    string

    Permission id

    description

    string

    Description of speicific part xxx

    permissionId

    string

    Permission id

    name

    string

    Service permission name

    {
      "id": "Permission id",
      "serviceId": "dashboard",
      "name": "plugin/getAvailable",
      "description": "Description of speicific part xxx",
      "updatedBySub": "infomaker_b8b9373b-a30d-459d-a44d-f270afb5e581"
    }
    "errors.api.BadRequestError"
    "errors.api.InternalServerError"

    permission:gl-news:opencontent:view

    Will give the application the opencontent:view permission only in the gl-news unit

    permission:*:opencontent:view

    Will give the application the opencontent:view permission in all units in the org

    role:gl-news:opencontent:readOnly

    Will give the application all permissions in the opencontet:readOnly role only in the gl-news unit.

    role:*:opencontent:readOnly

    Will give the application all permissions in the opencontet:readOnly role in all units in the og.

    Admin API page
    how to fetch access-tokens
    documentation for a full description
    fetch an access-token
    section about rotation of credentials
    documentation for a full description
    fetch an access-token
    section about rotation of credentials
    Organization Applications
    Fetching and using Access Tokens
    http://localhost:8888
    https://github.com/FiloSottile/mkcert
    https://caddyserver.com/docs/install
    https://demo.local.infomaker.io
    https://demo.local.infomaker.io
    [
      {
        "id": "Service id",
        "name": "dashboard",
        "description": "Description of speicific part xxx",
        "updatedBySub": "infomaker_b8b9373b-a30d-459d-a44d-f270afb5e581"
      }
    ]
    "errors.api.BadRequestError"
    "errors.api.InternalServerError"
    {
      "id": "Service id",
      "name": "dashboard",
      "description": "Description of speicific part xxx",
      "updatedBySub": "infomaker_b8b9373b-a30d-459d-a44d-f270afb5e581"
    }
    "errors.api.BadRequestError"
    "errors.api.InternalServerError"
    ""
    "errors.api.BadRequestError"
    "errors.api.InternalServerError"
    {
      "description": "Description of speicific part xxx"
    }
    "errors.api.BadRequestError"
    "errors.api.InternalServerError"
    {
      "name": "dashboard"
    }
    "errors.api.BadRequestError"
    "errors.api.InternalServerError"
    {
      org: []
      units: {
        unit1: [
          writer:access
          dashboard:access
        ],
        unit2: [
          writer:access
        ],
        unit3: [
          dashboard:access
        ]
      }
    }
    {
      org: []
      units: {
        unit1: [
          writer:access
        ],
        unit2: [
          writer:access
        ],
        unit3: []
      }
    }
    [
      {
        "id": "Internal application ID",
        "serviceId": "Service id",
        "name": "my-internal-application",
        "description": "Description of speicific part xxx"
      }
    ]
    "errors.api.BadRequestError"
    "errors.api.InternalServerError"
    {
      "id": "Internal application ID",
      "serviceId": "Service id",
      "name": "my-internal-application",
      "description": "Description of speicific part xxx"
    }
    "errors.api.BadRequestError"
    "errors.api.InternalServerError"
    {
      "id": "Internal application credential ID",
      "clientSecret": "xxxxxx",
      "sanitizedClientSecret": "x*****x"
    }
    "errors.api.BadRequestError"
    "errors.api.InternalServerError"
    ""
    "errors.api.BadRequestError"
    "errors.api.InternalServerError"
    ""
    "errors.api.BadRequestError"
    "errors.api.InternalServerError"
    {
      "id": "Internal application ID",
      "serviceId": "Service id",
      "name": "my-internal-application",
      "description": "Description of speicific part xxx"
    }
    "errors.api.BadRequestError"
    "errors.api.InternalServerError"
    [
      {
        "id": "Permission id",
        "serviceId": "dashboard",
        "name": "plugin/getAvailable",
        "description": "Description of speicific part xxx",
        "updatedBySub": "infomaker_b8b9373b-a30d-459d-a44d-f270afb5e581"
      }
    ]
    "errors.api.BadRequestError"
    "errors.api.InternalServerError"
    {
      "id": "Permission id",
      "serviceId": "dashboard",
      "name": "plugin/getAvailable",
      "description": "Description of speicific part xxx",
      "updatedBySub": "infomaker_b8b9373b-a30d-459d-a44d-f270afb5e581"
    }
    "errors.api.BadRequestError"
    "errors.api.InternalServerError"
    {}
    "errors.api.BadRequestError"
    "errors.api.InternalServerError"
    {
      "description": "Description of speicific part xxx"
    }
    "errors.api.BadRequestError"
    "errors.api.InternalServerError"
    {
      "name": "plugin/getAvailable"
    }
    "errors.api.BadRequestError"
    "errors.api.InternalServerError"
    permission:gl-news:opencontent:view permission:gl-news:opencontent:write
    docker run -p 8888:80 nginxdemos/hello
    mkdir ~/certificates 
    cd ~/certificates 
    mkcert "*.local.infomaker.io"
    mkcert -install
    chmod +r *.pem  # might not be needed
    demo.local.infomaker.io {
    
        tls /home/jacob/certificates/_wildcard.local.infomaker.io.pem /home/jacob/certificates/_wildcard.local.infomaker.io-key.pem
    
        reverse_proxy localhost:8888 {
            header_up Host                {host}
            header_up Origin              {host}
            header_up X-Real-IP           {remote}
            header_up X-Forwarded-Host    {host}
            header_up X-Forwarded-Server  {host}
            header_up X-Forwarded-Port    {port}
            header_up X-Forwarded-For     {remote}
            header_up X-Forwarded-Proto   {scheme}
            header_down Access-Control-Allow-Origin       https://demo.local.infomaker.io
            header_down Access-Control-Allow-Credentials  true
        }
    }
    
    cd ~/
    caddy start
    caddy adapt
    caddy reload
    127.0.0.1 demo.local.infomaker.io
    cd ~/
    caddy adapt
    caddy reload
    127.0.0.1 WHATEVER-SERVICE-NAME-YOU-WANT.local.infomaker.io
    NODE_EXTRA_CA_CERTS=$(mkcert -CAROOT)/rootCA.pem

    profile

    https://imas.imid.infomaker.io
    https://login.microsoftonline.com/b77b73ba-4156-4e43-940b-aa34693839db/v2.0/.well-known/openid-configuration

    Units

    /units.get

    GET https://admin-api.imid.infomaker.io/v1/units.get

    Get unit by id

    Query Parameters

    Name
    Type
    Description

    /units.list

    GET https://admin-api.imid.infomaker.io/v1/units.list

    List units

    Query Parameters

    Name
    Type
    Description

    /units.create

    POST https://admin-api.imid.infomaker.io/v1/units.create

    Create unit

    Request Body

    Name
    Type
    Description

    /units.delete

    POST https://admin-api.imid.infomaker.io/v1/units.delete

    Delete unit by id

    Request Body

    Name
    Type
    Description

    /units.setDescription

    POST https://admin-api.imid.infomaker.io/v1/units.setDescription

    Set unit description by id

    Request Body

    Name
    Type
    Description

    /units.setDisplayName

    POST https://admin-api.imid.infomaker.io/v1/units.setDisplayName

    Set unit display name by id

    Request Body

    Name
    Type
    Description

    /units.setName

    POST https://admin-api.imid.infomaker.io/v1/units.setName

    Set unit name by id

    Request Body

    Name
    Type
    Description

    Organization applications

    /organizationApplications.get

    GET https://admin-api.imid.infomaker.io/v1/organizationApplications.get

    Get organization application

    Subjects

    /subjects.get

    GET https://admin-api.imid.infomaker.io/v1/subjects.get

    Get subject by id

    Query Parameters
    Name
    Type
    Description

    organizationApplicationId

    string

    Organization application ID

    {
      "id": "Organization application ID",
      "organizationId": "Organization id",
      "name": "my-organization-application",
      "description": "Description of speicific part xxx"
    }
    "errors.api.BadRequestError"
    "errors.api.InternalServerError"

    /organizationApplications.list

    GET https://admin-api.imid.infomaker.io/v1/organizationApplications.list

    List organization applications

    Path Parameters

    Name
    Type
    Description

    string

    /organizationApplications.create

    POST https://admin-api.imid.infomaker.io/v1/organizationApplications.create

    Create organization application

    Request Body

    Name
    Type
    Description

    organizationId

    string

    Organization id

    name

    string

    Organization application name

    description

    string

    Description of speicific part xxx

    groups

    array

    undefined

    /organizationApplications.createCredential

    POST https://admin-api.imid.infomaker.io/v1/organizationApplications.createCredential

    Create organization application credentials

    Request Body

    Name
    Type
    Description

    organizationApplicationId

    string

    Organization application ID

    /organizationApplications.delete

    POST https://admin-api.imid.infomaker.io/v1/organizationApplications.delete

    Delete organization application

    Request Body

    Name
    Type
    Description

    organizationApplicationId

    string

    Organization application ID

    /organizationApplications.deleteCredential

    POST https://admin-api.imid.infomaker.io/v1/organizationApplications.deleteCredential

    Delete organization application credential

    Request Body

    Name
    Type
    Description

    organizationApplicationId

    string

    Organization application ID

    organizationClientCredentialId

    string

    Organization application credential ID

    /organizationApplications.modify

    POST https://admin-api.imid.infomaker.io/v1/organizationApplications.modify

    Modify organization application

    Request Body

    Name
    Type
    Description

    organizationApplicationId

    string

    Organization application ID

    name

    string

    Organization application name

    description

    string

    Description of speicific part xxx

    groups

    array

    undefined

    Query Parameters
    Name
    Type
    Description

    subjectId

    string

    Subject id

    {
      "id": "Subject id",
      "organizationId": "Organization id",
      "organizationSubject": "[email protected]",
      "blocked": false,
      "updatedBySub": "infomaker_b8b9373b-a30d-459d-a44d-f270afb5e581"
    }
    "errors.api.BadRequestError"
    "errors.api.InternalServerError"

    /subjects.list

    GET https://admin-api.imid.infomaker.io/v1/subjects.list

    List subjects by id

    Path Parameters

    Name
    Type
    Description

    string

    /subjects.me

    GET https://admin-api.imid.infomaker.io/v1/subjects.me

    View data of currently logged in subject

    Path Parameters

    Name
    Type
    Description

    string

    /subjects.block

    POST https://admin-api.imid.infomaker.io/v1/subjects.block

    Block subject

    Request Body

    Name
    Type
    Description

    subjectId

    string

    Subject id

    /subjects.create

    POST https://admin-api.imid.infomaker.io/v1/subjects.create

    Create subject

    Request Body

    Name
    Type
    Description

    organizationId

    string

    Organization id

    organizationSubject

    string

    Organization subject

    /subjects.delete

    POST https://admin-api.imid.infomaker.io/v1/subjects.delete

    Delete subject by id

    Request Body

    Name
    Type
    Description

    subjectId

    string

    Subject id

    /subjects.login

    POST https://admin-api.imid.infomaker.io/v1/subjects.login

    Login subject

    Request Body

    Name
    Type
    Description

    subjectId

    string

    Subject id

    /subjects.logout

    POST https://admin-api.imid.infomaker.io/v1/subjects.logout

    Logout subject

    Request Body

    Name
    Type
    Description

    subjectId

    string

    Subject id

    /subjects.setOrganizationSubject

    POST https://admin-api.imid.infomaker.io/v1/subjects.setOrganizationSubject

    Set subject organization subject by id

    Request Body

    Name
    Type
    Description

    subjectId

    string

    Subject id

    organizationSubject

    string

    Organization subject

    /subjects.unblock

    POST https://admin-api.imid.infomaker.io/v1/subjects.unblock

    Unblock subject

    Request Body

    Name
    Type
    Description

    subjectId

    string

    Subject id

    updatedBySub

    string

    Organization subject

    unitId

    string

    UUIDv4

    id

    string

    Unit id

    name

    string

    Unit name

    displayName

    string

    Unit display name

    organizationId

    string

    Organization id

    organizationId

    string

    Organization id

    name

    string

    Unit name

    displayName

    string

    Unit display name

    description

    string

    Description of speicific part xxx

    unitId

    string

    UUIDv4

    unitId

    string

    UUIDv4

    description

    string

    Description of speicific part xxx

    unitId

    string

    UUIDv4

    displayName

    string

    Unit display name

    unitId

    string

    UUIDv4

    name

    string

    Unit name

    {
      "id": "Unit id",
      "organizationId": "Organization id",
      "name": "barometern",
      "displayName": "Barometern OT",
      "description": "Description of speicific part xxx",
      "updatedBySub": "infomaker_b8b9373b-a30d-459d-a44d-f270afb5e581"
    }
    "errors.api.BadRequestError"
    "errors.api.InternalServerError"
    [
      {
        "id": "Organization application ID",
        "organizationId": "Organization id",
        "name": "my-organization-application",
        "description": "Description of speicific part xxx"
      }
    ]
    "errors.api.BadRequestError"
    "errors.api.InternalServerError"
    {
      "id": "Organization application ID",
      "organizationId": "Organization id",
      "name": "my-organization-application",
      "description": "Description of speicific part xxx"
    }
    "errors.api.BadRequestError"
    "errors.api.InternalServerError"
    {
      "id": "Organization application credential ID",
      "clientSecret": "xxxxxx",
      "sanitizedClientSecret": "x*****x"
    }
    "errors.api.BadRequestError"
    "errors.api.InternalServerError"
    ""
    "errors.api.BadRequestError"
    "errors.api.InternalServerError"
    ""
    "errors.api.BadRequestError"
    "errors.api.InternalServerError"
    {
      "id": "Organization application ID",
      "organizationId": "Organization id",
      "name": "my-organization-application",
      "description": "Description of speicific part xxx"
    }
    "errors.api.BadRequestError"
    "errors.api.InternalServerError"
    [
      {
        "id": "Subject id",
        "organizationId": "Organization id",
        "organizationSubject": "[email protected]",
        "blocked": false,
        "updatedBySub": "infomaker_b8b9373b-a30d-459d-a44d-f270afb5e581"
      }
    ]
    "errors.api.BadRequestError"
    "errors.api.InternalServerError"
    {
      "org": "infomaker",
      "sub": "[email protected]"
    }
    "errors.api.BadRequestError"
    "errors.api.InternalServerError"
    ""
    "errors.api.BadRequestError"
    "errors.api.InternalServerError"
    {
      "id": "Subject id",
      "organizationId": "Organization id",
      "organizationSubject": "[email protected]",
      "blocked": false,
      "updatedBySub": "infomaker_b8b9373b-a30d-459d-a44d-f270afb5e581"
    }
    "errors.api.BadRequestError"
    "errors.api.InternalServerError"
    ""
    "errors.api.BadRequestError"
    "errors.api.InternalServerError"
    ""
    "errors.api.BadRequestError"
    "errors.api.InternalServerError"
    ""
    "errors.api.BadRequestError"
    "errors.api.InternalServerError"
    {
      "organizationSubject": "[email protected]"
    }
    "errors.api.BadRequestError"
    "errors.api.InternalServerError"
    ""
    "errors.api.BadRequestError"
    "errors.api.InternalServerError"
    [
      {
        "id": "Unit id",
        "organizationId": "Organization id",
        "name": "barometern",
        "displayName": "Barometern OT",
        "description": "Description of speicific part xxx",
        "updatedBySub": "infomaker_b8b9373b-a30d-459d-a44d-f270afb5e581"
      }
    ]
    "errors.api.BadRequestError"
    "errors.api.InternalServerError"
    {
      "id": "Unit id",
      "organizationId": "Organization id",
      "name": "barometern",
      "displayName": "Barometern OT",
      "description": "Description of speicific part xxx",
      "updatedBySub": "infomaker_b8b9373b-a30d-459d-a44d-f270afb5e581"
    }
    "errors.api.BadRequestError"
    "errors.api.InternalServerError"
    ""
    "errors.api.BadRequestError"
    "errors.api.InternalServerError"
    {
      "description": "Description of speicific part xxx"
    }
    "errors.api.BHadRequestError"
    "errors.api.InternalServerError"
    {
      "displayName": "Barometern OT"
    }
    "errors.api.BadRequestError"
    "errors.api.InternalServerError"
    {
      "name": "barometern"
    }
    "errors.api.BadRequestError"
    "errors.api.InternalServerError"

    Roles

    /roles.get

    GET https://admin-api.imid.infomaker.io/v1/roles.get

    Get role by id

    Query Parameters

    Name
    Type
    Description

    /roles.list

    GET https://admin-api.imid.infomaker.io/v1/roles.list

    List roles

    Path Parameters

    Name
    Type
    Description

    /roles.listMappedGroups

    GET https://admin-api.imid.infomaker.io/v1/roles.listMappedGroups

    List all mapped groups by role id

    Query Parameters

    Name
    Type
    Description

    /roles.assignToGroup

    POST https://admin-api.imid.infomaker.io/v1/roles.assignToGroup

    Add group to role mapping

    Request Body

    Name
    Type
    Description

    /roles.create

    POST https://admin-api.imid.infomaker.io/v1/roles.create

    Create role

    Request Body

    Name
    Type
    Description

    /roles.delete

    POST https://admin-api.imid.infomaker.io/v1/roles.delete

    Delete role by id

    Request Body

    Name
    Type
    Description

    /roles.mapPermission

    POST https://admin-api.imid.infomaker.io/v1/roles.mapPermission

    Map permissision to role

    Request Body

    Name
    Type
    Description

    /roles.setDescription

    POST https://admin-api.imid.infomaker.io/v1/roles.setDescription

    Set role description by id

    Request Body

    Name
    Type
    Description

    /roles.setName

    POST https://admin-api.imid.infomaker.io/v1/roles.setName

    Set role name by id

    Request Body

    Name
    Type
    Description

    /roles.setParentRole

    POST https://admin-api.imid.infomaker.io/v1/roles.setParentRole

    Set role parent role by id

    Request Body

    Name
    Type
    Description

    /roles.unassignFromGroup

    POST https://admin-api.imid.infomaker.io/v1/roles.unassignFromGroup

    Delete group to role mapping

    Request Body

    Name
    Type
    Description

    /roles.unmapPermission

    POST https://admin-api.imid.infomaker.io/v1/roles.unmapPermission

    Unmap permission from role

    Request Body

    Name
    Type
    Description

    roleId

    string

    Role id

    string

    roleId

    string

    Role id

    organizationId

    string

    Organization id

    roleId

    string

    Role id

    organizationId

    string

    Organization id

    group

    string

    Organization group name

    unitId

    string

    Unit id

    serviceId

    string

    Service id

    name

    string

    Service role name

    parentRoleId

    string

    Role id

    description

    string

    Description of speicific part xxx

    roleId

    string

    Role id

    roleId

    string

    Role id

    permissionId

    string

    Permission id

    roleId

    string

    Role id

    description

    string

    Description of speicific part xxx

    roleId

    string

    Role id

    name

    string

    Service role name

    roleId

    string

    Role id

    parentRoleId

    string

    Role id

    roleId

    string

    Role id

    organizationId

    string

    Organization id

    group

    string

    Organization group name

    unitId

    string

    Unit id

    roleId

    string

    Role id

    permissionId

    string

    Permission id

    {
      "id": "Role id",
      "serviceId": "Service id",
      "name": "user",
      "description": "Description of speicific part xxx",
      "parentRoleId": "Role id",
      "updatedBySub": "infomaker_b8b9373b-a30d-459d-a44d-f270afb5e581"
    }
    "errors.api.BadRequestError"
    "errors.api.InternalServerError"
    [
      {
        "id": "Role id",
        "serviceId": "Service id",
        "name": "user",
        "description": "Description of speicific part xxx",
        "parentRoleId": "Role id",
        "updatedBySub": "infomaker_b8b9373b-a30d-459d-a44d-f270afb5e581"
      }
    ]
    "errors.api.BadRequestError"
    "errors.api.InternalServerError"
    [
      {
        "roleId": "Role id",
        "unitId": "Unit id",
        "organizationId": "Organization id",
        "group": "Auth team"
      }
    ]
    "errors.api.BadRequestError"
    "errors.api.InternalServerError"
    {
      "roleId": "Role id",
      "organizationId": "Organization id",
      "group": "Auth team",
      "unitId": "Unit id"
    }
    "errors.api.BadRequestError"
    "errors.api.InternalServerError"
    {
      "id": "Role id",
      "serviceId": "Service id",
      "name": "user",
      "description": "Description of speicific part xxx",
      "permissions": []
    }
    "errors.api.BadRequestError"
    "errors.api.InternalServerError"
    ""
    "errors.api.BadRequestError"
    "errors.api.InternalServerError"
    {
      "roleId": "Role id",
      "permissionId": "Permission id"
    }
    "errors.api.BadRequestError"
    "errors.api.InternalServerError"
    {
      "description": "Description of speicific part xxx"
    }
    "errors.api.BadRequestError"
    "errors.api.InternalServerError"
    {
      "name": "user"
    }
    "errors.api.BadRequestError"
    "errors.api.InternalServerError"
    {
      "parentRoleId": "Role id"
    }
    "errors.api.BadRequestError"
    "errors.api.InternalServerError"
    ""
    "errors.api.BadRequestError"
    "errors.api.InternalServerError"
    ""
    "errors.api.BadRequestError"
    "errors.api.InternalServerError"

    Fetching and using Access Tokens

    Introduction

    Access tokens are short lived JWT tokens that can identify either a user or an application. For an introduction to the JWT standard, see https://jwt.io/introduction.

    Because the tokens are short lived and since they can not be refreshed on their own, the verification of them are simpler than compared to ID-tokens. This means that they can be validated without the need for an IMSG reverse proxy.

    This document describes how to fetch and use Naviga ID access tokens.

    The links in these instructions point to the stage environment. To access the production systems, simply remove .stage from all URLs. For example: Stage Access-Token Service: Prod Access-Token Service:

    Fetch access tokens

    There are two ways to authenticate to retrieve an access token, either as a user or as an application.

    Locally cache and reuse Access Tokens for as long as they are valid (i.e. not expired). Do not fetch a new access token for each request you perform to a service API such as CCA or OC.

    Fetch access-token as logged in user

    As a logged in user, using ID-token

    POST https://access-token.stage.imid.infomaker.io/v1/token

    Choose ONE of the available ways to include the ID-token in the request.

    Query Parameters

    Name
    Type
    Description

    Headers

    Name
    Type
    Description

    Groups are only included in the access token if they have a "group to role"-mapping setup in Naviga ID Login.

    Fetch a scoped access-token as logged in user

    As a logged in user, using ID-token

    POST https://access-token.stage.imid.infomaker.io/v1/token

    Choose ONE of the available ways to include the ID-token in the request.

    Query Parameters

    Name
    Type
    Description

    Headers

    Name
    Type
    Description

    Request Body

    Name
    Type
    Description

    Groups are only included in the access token if they have a "group to role"-mapping setup in Naviga ID Login.

    See for an example on how to use scopes.

    Fetch access-token as application (using client credentials)

    If you haven't yet created an application in Naviga ID, se the page and follow the instructions there.

    As an application, using client credentials

    POST https://access-token.stage.imid.infomaker.io/v1/token

    Both JSON and form data are supported payload formats.

    Request Body

    Name
    Type
    Description

    Fetching access-tokens as application configured using scopes

    To use scopes, the application must have been configured with allowedScopes when created (and not using groups). If that is not the case, you can either modify the application by removing the groups and add allowedScopes, or simply create a new application.

    When fetching a token, in the scope field, specify the scopes that you wish to include in the token. If you specify more inclusive scopes than what is definied in the allowedScopes for your application, the req will fail. If you specify invalid scopes, such as with unit, service, role or pemission that does not exists in Naviga ID, the req will fail.

    All scopes have the following format

    ["permission"|"role"]:[unitName|"*"]:[serviceName]:[entityName]

    Below is a list of examples of scopes

    Scope
    Description

    Fetching access-token as application configured using groups

    Note that group-based applications are our legacy way of configuring authorization. It is still supported, by we highly recommend to transition to scope-based applications.

    CURL example. Start by storing client_id and client_secret in environment variable CLIENT_ID and CLIENT_SECRET respectively.

    CURL example that stores token in environment variable NAVIGA_ACCESS_TOKEN.

    Filtering access token permissions using scopes

    permission-filter-include-org

    Includes all requested permissions in the org array. Only one instance of the scope should exist.

    permission-filter-include-unit:{unitName}

    Includes all requested permissions in the specified unit array. Multiple instances of the scope can exist as long as the unit name is unique.

    Error if unitName does not exist or if sub does not have access to that unit

    Examples

    Authenticate using an Access Token

    Only send Access Tokens over HTTPS

    Simply include the Access Token in the Authorization header whenever you perform a request to a Naviga ID enabled service API, such as CCA and OC.

    Do not include the ID-token cookie when executing requests to APIs. If the service is using an IMSG, there's a chance of a "Too many tokens"-error.

    CURL example. Environment variable NAVIGA_ACCESS_TOKEN and NAVIGA_ORG needs to be set.

    imid_token

    string

    Value should be the ID token

    Cookie

    string

    ID-token set as dev-imidToken cookie. In client web applications, this is done by setting credentials: 'include'

    Authorization

    string

    Bearer ${ID token}

    imid_token

    string

    Value should be the ID token

    Cookie

    string

    ID-token set as dev-imidToken cookie. In client web applications, this is done by setting credentials: 'include'

    Authorization

    string

    Bearer ${ID token}

    scope*

    string

    Used to define requested scopes. Separate multiple scopes with spaces (" ")

    grant_type*

    string

    Must be set to urn:ietf:params:oauth:grant-type:token-exchange if scope is supplied

    client_secret*

    string

    client_id*

    string

    grant_type*

    string

    should be client_credentials

    scope

    string

    Used to define requested scopes. Separate multiple scopes with spaces (" ")

    permission:gl-news:opencontent:view

    If allowed, the token will get the opencontent:view permission only in the gl-news unit

    permission:*:opencontent:view

    If allowed, the token will get the opencontent:view permission in all units in the org

    role:gl-news:opencontent:readOnly

    If allowed, the token will get all permissions in the opencontet:readOnly role only in the gl-news unit.

    role:*:opencontent:readOnly

    If allowed, the token will get all permissions in the opencontet:readOnly role in all units in the org

    https://access-token.stage.imid.infomaker.io
    https://access-token.imid.infomaker.io
    below
    Managing Applications
    { 
      "access_token" : "eyJhbGciOiJIUzI1NiIsInR…", 
      "token_type": "Bearer", 
      "expires_in": 600 
    }
    { 
      "access_token" : "eyJhbGciOiJIUzI1NiIsInR…", 
      "token_type": "Bearer", 
      "expires_in": 600 
    }
    {
      "access_token" : "eyJhbGciOiJIUzI1NiIsInR…", 
      "token_type": "Bearer",
      "expires_in": 600
    }
    {
        // Response
    }
    {
        // Response
    }
    {
        // Response
    }
    {
        // Response
    }
    curl --data "grant_type=client_credentials&client_id=$CLIENT_ID&client_secret=$CLIENT_SECRET" https://access-token.stage.imid.infomaker.io/v1/token
    export NAVIGA_ACCESS_TOKEN=$(curl --silent --data "grant_type=client_credentials&client_id=$CLIENT_ID&client_secret=$CLIENT_SECRET" https://access-token.stage.imid.infomaker.io/v1/token | jq -r '.access_token')
    ## Original permissions
    ```
    {
        permissions: {
            org: [
                perm-1
                perm-2
            ],
            units: {
                barometern: [
                    perm-3
                ],
                smp: [
                    perm-4
                ]
            }
        }
    }
    ```
    ## permission-filter-include-org permission-filter-include-unit:smp
    ```
    {
        permissions: {
            org: [
                perm-1
                perm-2
            ],
            units: {
                smp: [
                    perm-4
                ]
            }
        }
    }
    ```
    ## permission-filter-include-org
    ```
    {
        permissions: {
            org: [
                perm-1
                perm-2
            ],
            units: {}
        }
    }
    ```
    ## permission-filter-include-unit:smp
    ```
    {
        permissions: {
            org: [],
            units: {
                smp: [
                    perm-4
                ]
            }
        }
    }
    ```
    Authorization : "Bearer $NAVIGA_ACCESS_TOKEN"
    curl -H "Authorization: Bearer $NAVIGA_ACCESS_TOKEN" https://demo.stage.imid.infomaker.io/v1/org/$NAVIGA_ORG/test
    

    Organizations

    /organizations.export

    GET https://admin-api.imid.infomaker.io/v1/organizations.export

    Get organization by id

    Query Parameters

    Name
    Type
    Description

    /organizations.get

    GET https://admin-api.imid.infomaker.io/v1/organizations.get

    Get organization by id

    Query Parameters

    Name
    Type
    Description

    /organizations.list

    GET https://admin-api.imid.infomaker.io/v1/organizations.list

    List organizations

    Path Parameters

    Name
    Type
    Description

    /organizations.listGroupToRoleMappings

    GET https://admin-api.imid.infomaker.io/v1/organizations.listGroupToRoleMappings

    List group to service role mappings by organization id

    Query Parameters

    Name
    Type
    Description

    /organizations.block

    POST https://admin-api.imid.infomaker.io/v1/organizations.block

    Block organization by id

    Request Body

    Name
    Type
    Description

    /organizations.create

    POST https://admin-api.imid.infomaker.io/v1/organizations.create

    Create organization

    Request Body

    Name
    Type
    Description

    /organizations.delete

    POST https://admin-api.imid.infomaker.io/v1/organizations.delete

    Delete organization by id

    Request Body

    Name
    Type
    Description

    /organizations.import

    POST https://admin-api.imid.infomaker.io/v1/organizations.import

    Get organization by id

    Request Body

    Name
    Type
    Description

    /organizations.logout

    POST https://admin-api.imid.infomaker.io/v1/organizations.logout

    Logout organization by id

    Request Body

    Name
    Type
    Description

    /organizations.setClientId

    POST https://admin-api.imid.infomaker.io/v1/organizations.setClientId

    Set organization clientId

    Request Body

    Name
    Type
    Description

    /organizations.setClientSecret

    POST https://admin-api.imid.infomaker.io/v1/organizations.setClientSecret

    Update org client secret

    Request Body

    Name
    Type
    Description

    /organizations.setDisplayName

    POST https://admin-api.imid.infomaker.io/v1/organizations.setDisplayName

    Set organization display name

    Request Body

    Name
    Type
    Description

    /organizations.setForceLoginPrompt

    POST https://admin-api.imid.infomaker.io/v1/organizations.setForceLoginPrompt

    Set organization forceLoginPrompt

    Request Body

    Name
    Type
    Description

    /organizations.setGroupsClaim

    POST https://admin-api.imid.infomaker.io/v1/organizations.setGroupsClaim

    Set organization groupsClaim

    Request Body

    Name
    Type
    Description

    /organizations.setName

    POST https://admin-api.imid.infomaker.io/v1/organizations.setName

    Set organization name

    Request Body

    Name
    Type
    Description

    /organizations.setResponseMode

    POST https://admin-api.imid.infomaker.io/v1/organizations.setResponseMode

    Set organization responseMode

    Request Body

    Name
    Type
    Description

    /organizations.setScope

    POST https://admin-api.imid.infomaker.io/v1/organizations.setScope

    Set organization scope

    Request Body

    Name
    Type
    Description

    /organizations.setUseUserinfoEndpoint

    POST https://admin-api.imid.infomaker.io/v1/organizations.setUseUserinfoEndpoint

    Set organization useUserinfoEndpoint

    Request Body

    Name
    Type
    Description

    /organizations.setWellKnownConfigUrl

    POST https://admin-api.imid.infomaker.io/v1/organizations.setWellKnownConfigUrl

    Set organization wellKnownConfigUrl

    Request Body

    Name
    Type
    Description

    /organizations.setWhitelistCallbackUrls

    POST https://admin-api.imid.infomaker.io/v1/organizations.setWhitelistCallbackUrls

    Set organization whitelistCallbackUrls

    Request Body

    Name
    Type
    Description

    /organizations.unblock

    POST https://admin-api.imid.infomaker.io/v1/organizations.unblock

    Unblock organization by id

    Request Body

    Name
    Type
    Description

    clientId

    string

    OIDC client ID

    responseMode

    string

    OIDC response mode

    groupsClaim

    string

    Organization groups claim

    whitelistCallbackUrls

    array

    An array with callback whitelist URL

    clientSecret

    string

    undefined

    forceLoginPrompt

    boolean

    undefined

    useUserinfoEndpoint

    boolean

    undefined

    organizationId

    string

    Organization id

    organizationId

    string

    Organization id

    string

    organizationId

    string

    Organization id

    organizationId

    string

    Organization id

    name

    string

    Organization name

    displayName

    string

    Organization display name

    wellKnownConfigUrl

    string

    undefined

    scope

    string

    OIDC scope

    organizationId

    string

    Organization id

    organizationId

    string

    Organization id

    config

    object

    undefined

    organizationId

    string

    Organization id

    organizationId

    string

    Organization id

    clientId

    string

    OIDC client ID

    organizationId

    string

    Organization id

    clientSecret

    string

    OIDC client secret

    organizationId

    string

    Organization id

    displayName

    string

    Organization display name

    organizationId

    string

    Organization id

    forceLoginPrompt

    boolean

    undefined

    organizationId

    string

    Organization id

    groupsClaim

    string

    Organization groups claim

    organizationId

    string

    Organization id

    name

    string

    Organization name

    organizationId

    string

    Organization id

    responseMode

    string

    OIDC response mode

    organizationId

    string

    Organization id

    scope

    string

    OIDC scope

    organizationId

    string

    Organization id

    useUserinfoEndpoint

    boolean

    undefined

    organizationId

    string

    Organization id

    wellKnownConfigUrl

    string

    Organization well known config url

    organizationId

    string

    Organization id

    whitelistCallbackUrls

    array

    An array with callback whitelist URL

    organizationId

    string

    Organization id

    {}
    "errors.api.BadRequestError"
    "errors.api.InternalServerError"
    {
      "id": "Organization id",
      "name": "infomaker",
      "displayName": "Infomaker Scandinavia AB",
      "wellKnownConfigUrl": "http://example.com/.well-known.json",
      "scope": "openid profile email",
      "clientId": "foobarbaz",
      "responseMode": "query",
      "groupsClaim": "Groups",
      "whitelistCallbackUrls": "[\"infomaker.io\", \"infomaker-test.io\"]",
      "sanitizedClientSecret": "null",
      "forceLoginPrompt": false,
      "useUserinfoEndpoint": false,
      "blocked": false,
      "updatedBySub": "infomaker_b8b9373b-a30d-459d-a44d-f270afb5e581"
    }
    "errors.api.BadRequestError"
    "errors.api.InternalServerError"
    [
      {
        "id": "Organization id",
        "name": "infomaker",
        "displayName": "Infomaker Scandinavia AB",
        "wellKnownConfigUrl": "http://example.com/.well-known.json",
        "scope": "openid profile email",
        "clientId": "foobarbaz",
        "responseMode": "query",
        "groupsClaim": "Groups",
        "whitelistCallbackUrls": "[\"infomaker.io\", \"infomaker-test.io\"]",
        "sanitizedClientSecret": "null",
        "forceLoginPrompt": false,
        "useUserinfoEndpoint": false,
        "blocked": false,
        "updatedBySub": "infomaker_b8b9373b-a30d-459d-a44d-f270afb5e581"
      }
    ]
    "errors.api.BadRequestError"
    "errors.api.InternalServerError"
    [
      {
        "roleId": "Role id",
        "unitId": "Unit id",
        "organizationId": "Organization id",
        "group": "Auth team"
      }
    ]
    "errors.api.BadRequestError"
    "errors.api.InternalServerError"
    ""
    "errors.api.BadRequestError"
    "errors.api.InternalServerError"
    {
      "id": "Organization id",
      "name": "infomaker",
      "displayName": "Infomaker Scandinavia AB",
      "wellKnownConfigUrl": "http://example.com/.well-known.json",
      "scope": "openid profile email",
      "clientId": "foobarbaz",
      "responseMode": "query",
      "groupsClaim": "Groups",
      "whitelistCallbackUrls": "[\"infomaker.io\", \"infomaker-test.io\"]",
      "sanitizedClientSecret": "null",
      "forceLoginPrompt": false,
      "useUserinfoEndpoint": false,
      "blocked": false,
      "updatedBySub": "infomaker_b8b9373b-a30d-459d-a44d-f270afb5e581"
    }
    "errors.api.BadRequestError"
    "errors.api.InternalServerError"
    ""
    "errors.api.BadRequestError"
    "errors.api.InternalServerError"
    {}
    "errors.api.BadRequestError"
    "errors.api.InternalServerError"
    ""
    "errors.api.BadRequestError"
    "errors.api.InternalServerError"
    {
      "clientId": "foobarbaz"
    }
    "errors.api.BadRequestError"
    "errors.api.InternalServerError"
    {
      "sanitizedClientSecret": "foobarbaz"
    }
    "errors.api.BadRequestError"
    "errors.api.InternalServerError"
    {
      "name": "Infomaker Scandinavia AB"
    }
    "errors.api.BadRequestError"
    "errors.api.InternalServerError"
    {
      "forceLoginPrompt": false
    }
    "errors.api.BadRequestError"
    "errors.api.InternalServerError"
    {
      "groupsClaim": "Groups"
    }
    "errors.api.BadRequestError"
    "errors.api.InternalServerError"
    {
      "name": "infomaker"
    }
    "errors.api.BadRequestError"
    "errors.api.InternalServerError"
    {
      "responseMode": "query"
    }
    "errors.api.BadRequestError"
    "errors.api.InternalServerError"
    {
      "scope": "openid profile email"
    }
    "errors.api.BadRequestError"
    "errors.api.InternalServerError"
    {
      "useUserinfoEndpoint": false
    }
    "errors.api.BadRequestError"
    "errors.api.InternalServerError"
    {
      "wellKnownConfigUrl": "http://example.com/.well-known.json"
    }
    "errors.api.BadRequestError"
    "errors.api.InternalServerError"
    {
      "whitelistCallbackUrls": "[\"infomaker.io\", \"infomaker-test.io\"]"
    }
    "errors.api.BadRequestError"
    "errors.api.InternalServerError"
    ""
    "errors.api.BadRequestError"
    "errors.api.InternalServerError"

    Environment variables

    #Environment variables ##Environment variables

    ANALYTICS_BATCH_INTERVAL

    Analytics batch interval

    How long to wait before sending batched analytics events to Google Analytics if batch size has not been exceeded.

    Type
    Required
    Alias

    Default value:

    Example value:

    ANALYTICS_BATCH_SIZE

    Analytics batch size

    How many analytics events to batch before sending data to Google Analytics. Max 20.

    Type
    Required
    Alias

    Default value:

    Example value:

    AWS_USE_EMPTY_CREDENTIALS

    Use empty AWS credentials

    Set to true to use empty credentials for AWS. Only set if you use AWS mocks that do not require credentials.

    Type
    Required
    Alias

    Example value:

    CORS_ALLOWED_ADDITIONAL_HEADERS

    CORS allowed additional headers

    Any extra headers (other than Accept,Authorization,Content-Type,If-None-Match) used by the service that should be allowed when CORS in IMSG is activated.

    Type
    Required
    Alias

    Default value:

    Example value:

    CORS_ALLOWED_ORIGINS

    CORS allowed origins

    Origins that should be allowed by Access-Control-Allow-Origin. This will override the service's CORS configuration

    Type
    Required
    Alias

    Default value:

    Example value:

    CORS_ALLOW_ANY_HEADERS

    CORS allow any headers

    Allow any headers in CORS. This will reflect the value of access-control-request-headers into the response access-control-allow-headers. Use with care.

    Type
    Required
    Alias

    Example value:

    ECS_CONTAINER_METADATA_FILE

    Do not set manually. Filepath to the ECS container metadata file. Set automatically by ECS if ECS_ENABLE_CONTAINER_METADATA is set.

    Type
    Required
    Alias

    Example value:

    ENABLE_API_DOCUMENTATION

    Set to true to enable Swagger API documentation

    Type
    Required
    Alias

    Example value:

    FIREHOSE_ACCESS_KEY

    IAM user access key

    The access key for the IAM user connected to the specific Firehose stream.

    Type
    Required
    Alias

    Example value:

    FIREHOSE_AWS_REGION

    AWS region

    The aws region where the Firehose is install at

    Type
    Required
    Alias

    Example value:

    FIREHOSE_HOST_PATH

    Firehose host path

    The host path to where the Firehose is installed. Mostly used in testing

    Type
    Required
    Alias

    Example value:

    FIREHOSE_SECRET_KEY

    IAM user secret key

    The secret key for the IAM user connected to the specific Firehose stream.

    Type
    Required
    Alias

    Example value:

    FIREHOSE_STREAM_NAME

    Firehose stream name

    The chosen name of the Firehose Delivery stream to send data to.

    Type
    Required
    Alias

    Example value:

    GRACE_PERIOD_TTL

    State API grace period

    How long to stay in grace once connection to the state API is lost. Defaults to 60 minutes.

    Type
    Required
    Alias

    Default value:

    Example value:

    IMAS_URL

    IMAS URL

    URL to IMAS

    Type
    Required
    Alias

    Example value:

    IMID_COOKIE_DOMAINS

    IMID cookie domains

    Domains to restrict the IMID cookies to. Usually infomaker.io

    Type
    Required
    Alias

    Default value:

    Example value:

    IMID_COOKIE_PREFIX

    IMID cookie prefix

    Prefix to apply to IMID token cookie. Defaults to none.

    Ex. if set to "dev", the cookie name will be "dev_imidToken"

    In production this should always be unset.

    Type
    Required
    Alias

    Example value:

    IMID_COOKIE_SAME_SITE

    IMID cookie SameSite

    Sets the SameSite directive on the IMID token cookie. Defaults to Lax. If set to 'none', the SameSite` directive will not be set.

    In production this should always be unset or set to lax`

    Type
    Required
    Alias

    Default value:

    Example value:

    IMID_COOKIE_SECURE

    IMID cookie Secure

    If the Secure flag should be set on the IMID token cookie. Defaults to true.

    In production this should always be unset or set to true

    Type
    Required
    Alias

    Default value:

    Example value:

    IM_LOG_LEVEL

    Log level

    Log level used by Bunyan. See for details

    Type
    Required
    Alias

    Default value:

    Example value:

    IM_LOG_NAME

    Log name

    Log name used by Bunyan. See for details

    Type
    Required
    Alias

    Default value:

    Example value:

    INCLUDE_GROUPS_IN_SERVICE_TOKEN

    Will perserve the groups claim from IMID token in the Service Token

    Type
    Required
    Alias

    Example value:

    INCLUDE_IMID_TOKEN_IN_REQUEST

    Include IMID token in request

    If enabled, authenticated requests to the service will contain the IMID token in the x-imid-token header. Note: Always make sure this header is never exposed. Only enable if access to the IMID token is necessary.

    Type
    Required
    Alias

    Example value:

    INTERNAL_SERVICE_URL

    Internal service URL

    URL where the service protected by IMSG can be reached

    Type
    Required
    Alias

    Example value:

    LEGACY_MODE_ONLY_INCLUDE_UNITS_WITH_EXPLICITLY_MAPPED_PERMISSIONS_IN_SERVICE_TOKEN

    Should only be set for legacy services not yet updated. If set, units without explicit permissions will not be included in the service token and org permissions for those units are ignored.

    Type
    Required
    Alias

    Example value:

    ONLY_ACCEPT_ID_TOKENS

    Only accept ID tokens

    If enabled, only ID tokens will be accepted as valid tokens. Access tokens will be rejected with an invalid token type error.

    Type
    Required
    Alias

    Example value:

    PORT

    HTTP port

    Port to run the HTTP server on

    Type
    Required
    Alias

    Example value:

    REFRESH_BACKOFF_TIMEOUT

    Modify refresh backoff timeout

    Do not modify unless for tests. Changes the default backoff time when refresh fails with other than 403 error.

    Type
    Required
    Alias

    Default value:

    Example value:

    SERVICE_ADMIN_INFOMAKER_GROUPS

    Service admin Infomaker groups

    Infomaker groups which should make subscribers service admininstrator for this service.

    Type
    Required
    Alias

    Default value:

    Example value:

    SERVICE_MAINTAINER

    Service maintainer

    Email or name used to identify who is responsible for the service.

    Type
    Required
    Alias

    Default value:

    Example value:

    SERVICE_NAME

    Service name

    Name of the service protected by IMSG

    Type
    Required
    Alias

    Default value:

    Example value:

    SERVICE_TOKEN_SIGN_SECRET

    Service token secret

    Shared secret between IMSG and the service protected by IMSG

    Type
    Required
    Alias

    Example value:

    STATE_API_READ_SECRET

    Internal API secret

    Secret used to access state API.

    Type
    Required
    Alias

    Example value:

    STATE_API_STARTUP_TIMEOUT

    State API grace period

    How long to wait for startup before timing out.

    Type
    Required
    Alias

    Example value:

    STATE_API_URL

    AWS region

    URL to state API.

    Type
    Required
    Alias

    Example value:

    TELEMETRY_API_URL

    Telemetry API URL

    URL to telemetry API

    Type
    Required
    Alias

    Example value:

    Milliseconds (integer)

    False

    Integer

    False

    Boolean

    False

    Comma separated values (string)

    False

    Comma separated values (string)

    False

    Boolean

    False

    String

    False

    Boolean

    False

    String

    False

    String

    False

    String

    False

    String

    False

    String

    False

    Milliseconds (integer)

    False

    String

    True

    Comma separated values (string)

    False

    IMID_COOKIE_DOMAIN, IMID_TOKEN_COOKIE_DOMAIN

    String

    False

    Enum (string) [Strict, Lax, false]

    False

    Boolean

    False

    Enum (string) [trace, debug, info, warn, error, fatal]

    False

    String

    False

    SERVICE_NAME

    Boolean

    False

    Boolean

    False

    String

    True

    Boolean

    False

    Boolean

    False

    Integer

    True

    Milliseconds (integer)

    False

    Comma separated values (string)

    False

    String

    False

    String

    False

    String

    True

    String

    True

    Milliseconds (integer)

    True

    String

    True

    String

    False

    Bunyan docs - Levels
    Bunyan docs - Introduction
    10000
    ANALYTICS_BATCH_INTERVAL=10000
    10
    ANALYTICS_BATCH_SIZE=8080
    AWS_USE_EMPTY_CREDENTIALS=false
    []
    CORS_ALLOWED_ADDITIONAL_HEADERS=service-custom-header
    []
    CORS_ALLOWED_ORIGINS="https://example.com, https://foo.bar"
    CORS_ALLOW_ANY_HEADERS=true
    ECS_CONTAINER_METADATA_FILE=/var/lib/ecs/data/metadata/*task_id*/*container_name*/ecs-container-metadata.json
    ENABLE_API_DOCUMENTATION=false
    FIREHOSE_ACCESS_KEY=UA-000000-2
    FIREHOSE_AWS_REGION=UA-000000-2
    FIREHOSE_HOST_PATH=http://firehose.com
    FIREHOSE_SECRET_KEY=UA-000000-2
    FIREHOSE_STREAM_NAME=imid-firehose
    3600000
    GRACE_PERIOD_TTL=3600000
    IMAS_URL=https://example.com
    [ 'infomaker.io' ]
    IMID_COOKIE_DOMAINS=example.com
    IMID_COOKIE_PREFIX=prod
    'Lax'
    IMID_COOKIE_SAME_SITE=Lax
    true
    IMID_COOKIE_SECURE=true
    'debug'
    IM_LOG_LEVEL=debug
    'imsg'
    IM_LOG_NAME="My service"
    INCLUDE_GROUPS_IN_SERVICE_TOKEN=true
    INCLUDE_IMID_TOKEN_IN_REQUEST=false
    INTERNAL_SERVICE_URL=https://example.com
    LEGACY_MODE_ONLY_INCLUDE_UNITS_WITH_EXPLICITLY_MAPPED_PERMISSIONS_IN_SERVICE_TOKEN=true
    ONLY_ACCEPT_ID_TOKENS=false
    PORT=8080
    30000
    REFRESH_BACKOFF_TIMEOUT=10000
    []
    SERVICE_ADMIN_INFOMAKER_GROUPS="Writer team, Dashboard team"
    'No maintainer'
    [email protected]
    'imsg'
    SERVICE_NAME=Writer
    SERVICE_TOKEN_SIGN_SECRET=so-secret
    STATE_API_READ_SECRET=so-secret
    STATE_API_STARTUP_TIMEOUT=10000
    STATE_API_URL=https://example.com
    TELEMETRY_API_URL=https://example.com