How to setup a multitenant Connect2id server

The multitenant edition of the Connect2id server can host multiple OpenID Connect provider / OAuth 2.0 authorisation servers as isolated tenants with their own issuer URL for the minted tokens and other configuration.

Tenant registration

Each tenant is identified by a unique tenant ID (tid) and must be registered with its entire configuration via the tenants web API.

The tid naming rules are those for internet host names which means they can be readily used as DNS labels, e.g.

https://[tid].example.com

Example tenant registration request:

POST /tenants/rest/v1/ HTTP/1.1
Host: c2id.com
Authorization: Bearer ztucZS1ZyFKgh0tUEruUtiSTXhnexmd6
Content-Type: application/json

{
  "tid"   : "t123",
  "props" : { "op.issuer"         : "https://t1.example.com",
              "jose.jwkSet"       : "eyAia2V5cyIgOiBbIHsgImt0eSIgOiAiUl...",
              "op.authz.endpoint" : "https://t1.example.com/login",
              "..."               : "..." }
}

Individual tenants can be decorated with attributes, temporarily disabled and of course deleted.

Reverse proxy configuration

Each HTTP request to the multitenant Connect2id server must include a special header identifying the tenant. This can be either the tid or the exact configured issuer URI.

Identifying the tenant by its tid in a Tenant-ID header:

POST /authz-sessions/rest/v3/ HTTP/1.1
Host: c2id.com
Tenant-ID: t1
Authorization: Bearer ztucZS1ZyFKgh0tUEruUtiSTXhnexmd6
Content-Type: application/json

{
  "query" : "response_type=code&scope=openid%2020email&client_id=s6BhdR&state=af0ifjsldkj&redirect_uri=https%3A%2F%2Fclient.example.org%2Fcb"
}

Identifying the tenant by its issuer URI in a Issuer header:

POST /authz-sessions/rest/v3/ HTTP/1.1
Host: c2id.com
Issuer: https://t1.example.com
Authorization: Bearer ztucZS1ZyFKgh0tUEruUtiSTXhnexmd6
Content-Type: application/json

{
  "query" : "response_type=code&scope=openid%2020email&client_id=s6BhdR&state=af0ifjsldkj&redirect_uri=https%3A%2F%2Fclient.example.org%2Fcb"
}

The Tenant-ID header is the recommended method because it allows for the issuer URI to be changed without the need to reconfigure the reverse proxy.

In your reverse HTTP proxy configuration create a pass block for each tenant and set the appropriate Tenant-ID or Issuer header there.

With nginx, assuming the Connect2id server is at http://192.168.0.1:8080/, the blocks could look like:

server {
    server_name t1.example.com;
    location / {
        proxy_pass http://192.168.0.1:8080/;
        proxy_set_header Tenant-ID "t1";
        proxy_set_header Issuer "";
    }
}

server {
    server_name t2.example.com;
    location / {
        proxy_pass http://192.168.0.1:8080/;
        proxy_set_header Tenant-ID "t2";
        proxy_set_header Issuer "";
    }
}

If there are many tenants or tenants are going to be dynamically added or removed the proxy configuration could be set to compose the Tenant-ID dynamically, by extracting the tid from the subdomain. With this configuration there is no need to define a pass block for each tenant. Requests for an invalid subdomain (tenant) will produce a HTTP 500 error with "Invalid tenant ID" message at the Connect2id server.

server {
    server_name ~^(?<subdomain>.*)\.example\.com$;
    proxy_set_header Tenant-ID $subdomain;
    proxy_set_header Issuer "";
}

Important: Remember to clear the tenant identification header that isn't used, e.g. Issuer, to prevent HTTP clients from setting it.

Note the above configuration doesn't include any TLS termination settings. For mTLS check the separate guide.

DNS configuration

Make sure the issuer URI for each tenant resolves in the DNS to the reverse proxy host.

A tenant can choose to create a DNS alias record using an arbitrary name that points to their subdomain managed by the Connect2id server reverse proxy.

myidp.com   ALIAS   t1.example.com

In that case the reverse proxy needs to be provisioned with a valid server TLS certificate for DNS alias record (myidp.com).

Alternatively, the tenant can host their own reverse proxy with server TLS termination and certificate, and pass requests (always with TLS!) to the Connect2id server reverse proxy.

Easing anticipated migration to multi-tenant edition with DynamoDB

If you are deploying a new single-tenant Connect2id server with a DynamoDB backend and anticipate an eventual migration to the multi-tenant edition configure your database connection with those additional properties:

  • dynamodb.applyRangeKey -- set the optional DynamoDB range (sort) key name to tid.

  • dynamodb.rangeKeyValue -- set the key value to the tenant ID that will be given to the hosted OpenID provider / OAuth 2.0 authorisation server.

Example:

dynamodb.applyRangeKey=tid
dynamodb.rangeKeyValue=t123