Skip to content

Additional Issuers📜

This document explains how to configure multiple JWT issuers (OIDC providers) in authservice using the additionalIssuers feature.

Overview📜

The additionalIssuers feature allows you to configure multiple JWT token issuers beyond the primary issuer. This is useful when:

  • You need to accept tokens from multiple identity providers
  • Different applications or services use different OIDC providers
  • You want to restrict certain issuers to specific hosts/applications

How It Works📜

Primary Issuer📜

The primary issuer is configured using either:

  • issuer_uri and jwks_uri values, OR
  • global.oidc.host and global.oidc.realm (for Keycloak-based setups)

This primary issuer is always included in the authentication and authorization policies.

Additional Issuers Configuration📜

Additional issuers are configured via the additionalIssuers array in values.yaml. Each additional issuer can optionally specify which hosts it should apply to.

Configuration📜

Basic Configuration (No Host Restrictions)📜

When you add additional issuers without specifying hosts, they work for all hosts (except those explicitly restricted to other issuers):

additionalIssuers:
  - issuer: "https://issuer1.example.com"
    jwks_uri: "https://issuer1.example.com/.well-known/jwks.json"
  - issuer: "https://issuer2.example.com/auth"
    jwks_uri: "https://issuer2.example.com/.well-known/jwks.json"

Result: Both additional issuers work for all hosts, alongside the primary issuer.

Host-Restricted Configuration📜

You can restrict an additional issuer to specific hosts by adding a hosts array:

additionalIssuers:
  - issuer: "https://partner-idp.example.com"
    jwks_uri: "https://partner-idp.example.com/.well-known/jwks.json"
    hosts:
      - "partner-app.example.com"
      - "partner-api.example.com"

Result: This issuer ONLY works for the specified hosts. The primary issuer and other additional issuers are EXCLUDED from these hosts.

Mixed Configuration📜

You can mix host-restricted and non-restricted issuers:

additionalIssuers:
  # This issuer works for all hosts (except those restricted below)
  - issuer: "https://corp-sso.example.com"
    jwks_uri: "https://corp-sso.example.com/.well-known/jwks.json"

  # This issuer ONLY works for specific hosts
  - issuer: "https://partner-idp.example.com"
    jwks_uri: "https://partner-idp.example.com/.well-known/jwks.json"
    hosts:
      - "partner-app.example.com"
      - "partner-api.example.com"

Generated Istio Resources📜

RequestAuthentication (JWT Validation)📜

The RequestAuthentication resource validates JWT tokens from all configured issuers:

apiVersion: security.istio.io/v1beta1
kind: RequestAuthentication
metadata:
  name: jwt-authn
spec:
  jwtRules:
    # Primary issuer
    - issuer: https://login.dso.mil/auth/realms/baby-yoda
      jwksUri: https://login.dso.mil/auth/realms/baby-yoda/protocol/openid-connect/certs
      forwardOriginalToken: true

    # Additional issuers (all included regardless of host restrictions)
    - issuer: https://partner-idp.example.com
      jwksUri: https://partner-idp.example.com/.well-known/jwks.json
      forwardOriginalToken: true

AuthorizationPolicy (Access Control)📜

The AuthorizationPolicy controls which hosts accept tokens from which issuers. Each issuer gets its own separate rule.

Without Host Restrictions📜

When no additional issuers have host restrictions, each issuer gets a simple rule:

apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
  name: jwt-authz
spec:
  action: ALLOW
  rules:
    # Primary issuer - applies to all hosts
    - from:
      - source:
          requestPrincipals:
          - "https://login.dso.mil/auth/realms/baby-yoda/*"

    # Additional issuer 1 - applies to all hosts
    - from:
      - source:
          requestPrincipals:
          - "https://corp-sso.example.com/*"

With Host Restrictions (notHosts)📜

When ANY additional issuer has host restrictions, the chart automatically adds notHosts constraints to prevent the primary issuer and unrestricted additional issuers from accessing the restricted hosts:

apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
  name: jwt-authz
spec:
  action: ALLOW
  rules:
    # Primary issuer - EXCLUDED from partner-app.example.com
    - from:
      - source:
          requestPrincipals:
          - "https://login.dso.mil/auth/realms/baby-yoda/*"
      to:
      - operation:
          notHosts:
          - "partner-app.example.com"

    # Additional issuer without hosts - EXCLUDED from partner-app.example.com
    - from:
      - source:
          requestPrincipals:
          - "https://corp-sso.example.com/*"
      to:
      - operation:
          notHosts:
          - "partner-app.example.com"

    # Additional issuer with hosts - ONLY for partner-app.example.com
    - from:
      - source:
          requestPrincipals:
          - "https://partner-idp.example.com/*"
      to:
      - operation:
          hosts:
          - "partner-app.example.com"

ServiceEntry (Network Access)📜

When Istio hardened mode is enabled (istio.hardened.enabled: true), a ServiceEntry is automatically created for each additional issuer to allow outbound HTTPS traffic to the JWKS endpoint:

apiVersion: networking.istio.io/v1beta1
kind: ServiceEntry
metadata:
  name: partner-idp-example-com-issuer
spec:
  hosts:
    - partner-idp.example.com
  location: MESH_EXTERNAL
  ports:
    - number: 443
      protocol: TLS
      name: https