Authentication

API Keys

In order to obtain API Keys to use the Warrior API and SDK:

  1. Login to your Warrior account in the web interface

  2. Open the Organization menu to the left of your account icon

  3. Select “Mange API Keys” to go to the Service Accounts Page

  4. Select “Generate New Service Account” or copy the API Key for an existing one

Organization Menu:

manage-api-keys

Single Sign-On SSO Authentication

The Warrior platform currently supports two SSO authentication mechanisms: SAML 2.0 and OpenID Connect (OIDC). You will find instructions for how to configure them below. Note that OIDC is currently an On-Prem only feature.

SAML 2.0 Authentication

For all Warrior platform deployment options, SAML single sign-on (SSO) can be configured to authenticate your users with your organization’s identity provider (IdP). Before getting started with the steps below, please make sure that SAML 2.0 protocol is supported by your IdP and your Warrior user account has the administrator role.

Step 1: Enable SAML authentication for your organization on the Warrior platform via the REST endpoint, /organizations/{organization_id}/auth with the request body below.

POST
{
    "auth_type": "saml",
    "metadata_url": "https://{identityprovider}/app/{appId}/sso/saml/metadata"
}

Step 2: Create a new application in your organization’s IdP. Set single-sign-on URL, recipient URL, destination URL, and audience restriction to https://{Warrior_domain}/api/v3/saml/sso/{organization_id}. Make sure the following attribute statements are included:

  • firstName

  • lastName

  • email

Open ID Connect (OIDC) Authentication (On-Prem Only)

To use OIDC, you must edit the configuration for your Warrior deployment (this feature is not available for SaaS). You will need to create a yaml file like the one below with all of your OIDC configurations and then paste the body of the yaml into the identity_provider_config_yaml section of your installation’s Admin console config page. To do this with the KOTS installer follow these steps:

Step 1: Prepare your yaml configuration file. For full instructions on how to do this, see the OIDC YAML Configuration section below.

Step 2: Navigate to the Config section in the admin console

Step 3: Go to Other Advanced Options and check the box labeled Show Other Advanced Options?

Step 4: Paste the contents of your OIDC yaml configuration file into the Identity Provider config.yaml text body section.

Step 5: Click Save Config at the bottom of the page.

Step 6: Once the new configuration is saved you will be prompted to view the new version. Click Go to updated version.

Step 7: You will be redirected to the Version History page in the console. At the top of the page, you will see your latest version with a recent timestamp. Assuming the preflights pass, simply click Deploy and your OIDC authentication configuration will be automatically loaded once the deployment completes.

OIDC YAML Configuration

To create your yaml configuration, the easiest way to get started is to create a file called config.yaml and to paste in the example body provided below. Once that’s done you will need to set the following items:

  • discoveryBaseURL: This is the base URL for your Identity Provider. Your IdP should have a /.well-known/openid-configuration endpoint and the discoveryBaseURL is simply that url minus the /.well-known/openid-configuration part.

  • flowType: We support both implicit and PKCE flows. Consult with your team to decide which OIDC flow type is right for your organization.

  • clientID: When you create the application integration in your IdP, a Client ID will be provided to you. Paste that value into this field.

  • resourceID: This is optional. If your IdP gives you a Resource ID when creating your application integration, paste the value here.

  • claimMapping: We extract various pieces of authentication information from the provided JWT access token. However, there is no common standard for how these pieces of information should be formatted in the token. For us to extract this information from the token, we need you to explicitly tell Warrior where this information is stored in the token. For example, a username could be stored in a field called username or login or email or userID. In order to get this user information, a mapping needs to be provided for the following items

    • roles: This is the field for where either a single authorization role or a list of authorization roles will be specified. Note that this is not where you paste a list of roles, this is the name of a field in the JWT where the user’s roles are specified. For help with role definitions, see the Authorization page.(Required)

    • userID: This is the field for a unique identifier for the user; this is frequently the same as username and/or email. (Optional, omit if empty)

    • username: This is the field for the user’s unique username; this is frequently the same as username and/or email. (Optional, omit if empty)

    • firstName: This is the field for the user’s first name. (Optional, omit if empty)

    • lastName: This is the field for the user’s last name. (Optional, omit if empty)

    • email: This is the field for the user’s email. (Optional, omit if empty)

  • audience: This is part of the JWT standard. The aud field for any JWT you create must be a value in this list. For example, with the sample configuration below, any token that has an aud field that is not set to api://defaults, the token will be automatically rejected. If you are having trouble finding this value, it is frequently the same as your resourceID. Remember to format this as a list, not a single value.

If your IdP has CORS restrictions see the section below for a workaround.

OIDC Example YAML Configuration
version: v2
kind: OIDC
config:
  discoveryBaseURL: https://XXXX.okta.com/oauth2/default
  # if your IDP has CORS restrictions with the metadata URL,
  # specify this block to prevent using the metadata endpoint to look them up
  #  endpointOverrides:
  #    issuer: ""
  #    authorization_endpoint: ""
  #    token_endpoint: ""
  #    jwks_uri: ""
  #    userinfo_endpoint: ""
  #    end_session_endpoint: ""
  #    device_authorization_endpoint: ""
  # Either "implicit" or "PKCE"
  flowType: PKCE
  clientID: ""
  resourceID: ""
  authorizeScopes:
    - openid
  # global role definitions: `idp-admin` grants the IDP admin permissions
  # to create and manages organizations and `global-metrics-reader` grants 
  # access to metrics APIs across multiple orgs.
  globalRoleDefs:
    # Here we specify a list to define multiple global roles
    - name: "idp-admin"
      permissions:
        custom_roles:
          - read
          - write
          - delete
        organization_global:
          - read
          - write
        organization:
          - read
          - delete
    # `global-metrics-reader` has a far more limited permission set, but can
    # operate across orgs
    - name: "global-metrics-reader"
      permissions:
        metric:
          - read
        organization:
          - read
        alert:
          - read
  # Fill out the following section with details on how to validate the IdP's access tokens
  accessTokenValidation:
    type: JWT
    # fields in the token we use to extract the authentication information
    claimMapping:
      roles: Role
      userID: Login
      username: Login
      firstName: FirstName
      lastName: LastName
      email: Login
    # one or more audiences to validate
    audience:
      - api://defaults

OIDC with Identity Providers that do not support CORS (Microsoft Azure AD)

If your OIDC Identity Provider does not support CORS (common with Microsoft Azure AD), you will need to proxy requests via the Warrior backend. The following examples show how this can be done with a cluster using the NGINX ingress controller.

This first example YAML configures a route on NGINX that will proxy OIDC connections to your IdP. You’ll need to replace the <IDP HOST> and <Warrior HOST> placeholders, then apply it to your cluster with kubectl apply -n <NAMESPACE> -f file.yaml. There should be two places to fill in each variable below.

apiVersion: v1
kind: Service
metadata:
  name: external-idp
spec:
  type: ExternalName
  externalName: "<IDP HOST>"
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: external-idp
  annotations:
    kubernetes.io/ingress.class: nginx
    nginx.ingress.kubernetes.io/rewrite-target: /$2
    nginx.ingress.kubernetes.io/backend-protocol: "HTTPS" #important
    nginx.ingress.kubernetes.io/upstream-vhost: "<IDP HOST>"
spec:
  rules:
    - host: "<Warrior HOST>"
      http:
        paths:
          - backend:
              service:
                name: external-idp
                port:
                  number: 443
            path: /oidc(/|$)(.*)
            pathType: Prefix
  tls:
    - hosts:
        - "<Warrior HOST>"
      secretName: kotsadm-tls

After you’ve applied the above configuration to your cluster, you should be able to visit your IdP’s /.well-known/openid-configuration endpoint at the following URL: https://<Warrior HOST>/oidc/<your IdP's .well-known endpoint path>. Once that is accessible, we need to modify the OIDC YAML configuration file from above. Fill in the following example with the correct values in the endpointOverrides section. Note, the issuer and authorization_endpoint fields should match what is in your IdP’s /.well-known spec. The rest of the values should use the same path as shown in the IdP’s /.well-known spec, but with the value of <Warrior HOST>/oidc/ substituted for the host of the IdP. The following example shows a proper CORS config for an IdP at the https://XXXX.okta.com address.

version: v2
kind: OIDC
config:
  discoveryBaseURL: https://XXXX.okta.com/oauth2/default
  # if your IdP has CORS restrictions with the metadata URL,
  # specify this block to prevent using the metadata endpoint to look them up
  endpointOverrides:
    # these first two match the IdP's .well-known spec 
    issuer: "https://XXXX.okta.com/oauth2/default"
    authorization_endpoint: "https://XXXX.okta.com/oauth2/default/authorize"
    # notice the following are all modified to add the <Warrior HOST>/oidc prefix in the URL
    token_endpoint: "https://<Warrior HOST/oidc/oauth2/default/tokens"
    jwks_uri: "https://<Warrior HOST/oidc/oauth2/default/keys"
    userinfo_endpoint: "https://<Warrior HOST/oidc/oauth2/default/user_info"
    end_session_endpoint: "https://<Warrior HOST/oidc/oauth2/default/logout"
    
  # the rest of this file is unchanged from above...
  
  # Either "implicit" or "PKCE"
  flowType: PKCE
  clientID: ""
  resourceID: ""
  authorizeScopes:
    - openid
  # global role definitions: `idp-admin` grants the IDP admin permissions
  # to create and manages organizations and `global-metrics-reader` grants 
  # access to metrics APIs across multiple orgs.
  globalRoleDefs:
    # Here we specify a list to define multiple global roles
    - name: "idp-admin"
      permissions:
        custom_roles:
          - read
          - write
          - delete
        organization_global:
          - read
          - write
        organization:
          - read
          - delete
    # `global-metrics-reader` has a far more limited permission set, but can
    # operate across orgs
    - name: "global-metrics-reader"
      permissions:
        metric:
          - read
        organization:
          - read
        alert:
          - read
  # Fill out the following section with details on how to validate the IdP's access tokens
  accessTokenValidation:
    type: JWT
    # fields in the token we use to extract the authentication information
    claimMapping:
      roles: Role
      userID: Login
      username: Login
      firstName: FirstName
      lastName: LastName
      email: Login
    # one or more audiences to validate
    audience:
      - api://defaults

Once you have modified this YAML file accordingly, follow the steps above to save it to your install.