Azure AD as OIDC provider
This how-to describes how to configure Azure AD as an OIDC provider for a tenant in an Avassa system. In the how-to we create a new tenant, an OIDC provider can of course be added to an existing tenant as well.
Prepare Azure AD
We need to prepare our Control Tower as an OIDC client in Azure AD. All this configuration is done in the Azure Active Directory config in Azure.
App Registration

Click New registration

Make sure you add a redirect URI here, the path is: <env-name>.<org-name>.avassa.net/oidc-callback
After saving, you will see something like this, make a note of the Application (client) ID

Client Secret
Next create a new secret by clicking Client credentialsand add a client secret.

Note the Value of the secret.
The client secret has an expiry date, so you will have to refresh this.
You will see this in the system:logs topic:
<ERROR> 2025-10-02 07:17:31.434675Z control-tower/ip-10-20-20-1: Failed to grant oidc token: Message from OIDC server (401) {"error":"invalid_client","error_description":"AADSTS7000222: The provided client secret keys for app '...' are expired. Visit the Azure portal to create new keys for your app: https://aka.ms/NewClientSecret, or consider using certificate credentials for added security: https://aka.ms/certCreds.
Endpoint URL
Next client Endpoints here:

And note OpenID Connect metadata document

Add email claim
To make sure the email address is available in the Avassa system, we need to
add the email claim. Click Token configuration and then Add optional claim.
Select Token type: ID and then select email and click Add.

Add user groups claim
For this tutorial, we will map Azure AD groups to policies in the Avassa System. To add groups as a claim, select the app registration and add groups claim:

Azure AD Information
You should now have the following values from Azure:
| client ID | dd3ef79f-b9b4-44bd-b1ec-e71b221e0e96 |
| client secret | LCq8Q~lls7H4AYpD-J2~dI1BjumZbbET8GXincAx |
| Discovery URL | https://login.microsoftonline.com/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/v2.0/.well-known/openid-configuration |
Configure OIDC for a tenant
First we will create a new tenant, in this example we will call this tenant popcorn-inc.
supctl replace tenants popcorn-inc <<EOF
name: popcorn-inc
kind: application-owner
policies:
- app-owner-tenant
EOF
Next we will generate a root token for this tenant.
Make sure you take note of the token below, it will be used in subsequent supctl calls below.
You can only call create-root once.
supctl do strongbox token create-root --name popcorn-inc
Warning: Providing --name on the command line is insecure. Consider using --name-prompt instead.
{
"accessor": "c51e2c8d-1cab-4d36-9880-294bc5529059",
"token": "6c1fa04e-463a-4e61-bcc9-fd1e072f16cc",
"creation-time": "2023-01-16T11:36:10.549630Z"
}
With the discovery URL, client ID and the secret from above, we can now create the oidc service.
NOTE 1: make sure allowed-redirect-uris match what you configured in Azure above.
NOTE 2: role-claim: groups will try to match all group names in the groups to oidc roles.
6c1fa04e-..is the token generated above
supctl -t 6c1fa04e-463a-4e61-bcc9-fd1e072f16cc replace strongbox authentication oidc-services azure-ad <<EOF
name: azure-ad
display-name: azure-ad
# Replace me
discovery-url: https://login.microsoftonline.com/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/v2.0/.well-known/openid-configuration
use-root-ca-certs: true
# Replace me
client-id: dd3ef79f-b9b4-44bd-b1ec-e71b221e0e96
# Replace me
client-secret: LCq8Q~lls7H4AYpD-J2~dI1BjumZbbET8GXincAx
verbose-logging: true
role-select:
role-claim: groups
allowed-redirect-uris:
# Replace me
- https://my-env.example.avassa.dev/oidc-callback
EOF
verbose-logging: true can be helpful while setting up and testing.
See troubleshooting for helpful logs.
Verbose logging should be disabled in production:
supctl -t 6c1fa04e-463a-4e61-bcc9-fd1e072f16cc merge strongbox authentication oidc-services azure-ad <<EOF
verbose-logging: false
EOF
Now we will create OIDC roles to match an Azure groups. Azure groups are sent
in the form of guids, you can find the roles in azure in the Groups menu,
there the group names and guid (Object Id) are listed.
dbb4bd8f-..is the Object Id for the Azure group.6c1fa04e-..is the token generated above
Here we match the dbb4bd8f-c8a9-45c1-a6d2-5456f2fcb6b9 group id to a root and user policy.
supctl -t 6c1fa04e-463a-4e61-bcc9-fd1e072f16cc create strongbox authentication oidc-services azure-ad roles <<EOF
name: dbb4bd8f-c8a9-45c1-a6d2-5456f2fcb6b9
# If the email claim is not present, deny access
required-claims:
- email
# Map email claim to username in the Avassa system
claim-mappings:
email: username
name: fullname
# Map this group to the following policies
token-policies:
- root
- user
EOF
Claim mappings
In the above example we map email from Azure AD to username in the Avassa system. This will ensure
the email address is logged in the audit trail logs and rendered in the UI.
The fullname mapping is optional, it will be used to render the user's name in the UI.
Test Login
To login, go to your environment and click change tenant

Click get login options and then login with azure-ad.

At this point you will be redirected to Azure and after logging in, redirected back into Control Tower.
Troubleshooting
In case login fails, you can find useful information in the following topics:
system:logssystem:audit-trail-log
supctl -t 6c1fa04e-463a-4e61-bcc9-fd1e072f16cc do volga topics system:logs consume --payload-only