description |
---|
Provisioning and configuration of accompanying Azure AD application.
|
{% hint style="warning" %} This feature is only available in team namespaces {% endhint %}
An accompanying Azure AD application can be automatically provisioned to your NAIS application.
The Azure AD application will be configured with sane defaults to enable usage in both authentication and/or authorization for web applications.
We generate a Kubernetes Secret containing the values needed for your application to integrate with Azure AD, e.g. credentials and URLs. The secret will automatically be mounted to the pods of your application during deploy.
Every deploy will trigger rotation of credentials, invalidating any passwords and keys that are not in use. In use in this context refers to all credentials that are currently mounted to an existing pod - regardless of their status (Running, CrashLoopBackOff, etc.). In other words, credential rotation should happen with zero downtime.
See the NAIS manifest.
The very minimal example configuration required in nais.yaml
to enable auto-provisioning of an Azure AD application for your application.
apiVersion: "nais.io/v1alpha1"
kind: "Application"
metadata:
name: nais-testapp
namespace: aura
labels:
team: aura
spec:
image: navikt/nais-testapp:65.0.0
azure:
application:
enabled: true
This will register an Azure AD application using the following naming scheme:
<cluster>:<metadata.namespace>:<metadata.name>
For the example above, the result would be:
dev-gcp:default:nais-testapp
You may find the application in the Azure Portal.
apiVersion: "nais.io/v1alpha1"
kind: "Application"
metadata:
name: nais-testapp
namespace: aura
labels:
team: aura
spec:
image: navikt/nais-testapp:65.0.0
azure:
application:
enabled: true
ingresses:
- "https://my.application"
- "https://my.application.dev.nais.io"
accessPolicy:
inbound:
rules:
- application: app-a
namespace: othernamespace
- application: app-b
A redirect URI, or reply URL, is the location that the authorization server will send the user to once the app has been successfully authorized, and granted an authorization code or access token. The code or token is contained in the redirect URI or reply token so it's important that you register the correct location as part of the app registration process.
-- Microsoft's documentation on reply URLs
{% hint style="info" %}
Note that spec.azure.application.replyURLs[]
can be omitted if spec.ingresses
are specified.
{% endhint %}
Each ingress specified will generate a reply URL using the formula:
spec.ingresses[n] + "/oauth2/callback"
In other words, this:
spec:
azure:
application:
enabled: true
ingresses:
- "https://my.application"
- "https://my.application.dev.nais.io"
is equivalent to this:
spec:
azure:
application:
enabled: true
replyURLs:
- "https://my.application/oauth2/callback"
- "https://my.application.dev.nais.io/oauth2/callback"
ingresses:
- "https://my.application"
- "https://my.application.dev.nais.io"
You may override the reply URLs manually by specifying spec.azure.application.replyURLs[]
.
{% hint style="danger" %}
Specifying spec.azure.application.replyURLs[]
will replace all the auto-generated reply URLs.
If you do override the reply URLs, make sure that you specify all the URLs that should be registered for the Azure AD application.
Ensure that these URLs conform to the restrictions and limitations of reply URLs as specified by Microsoft. {% endhint %}
If your application should accept access tokens from other applications using the on-behalf-of flow,
a spec.accessPolicy.inbound.rules[]
must be present:
spec:
accessPolicy:
inbound:
rules:
- application: app-a
namespace: othernamespace
- application: app-b
The above configuration will allow on-behalf-of access token requests from:
- application
app-a
in namespaceothernamespace
- application
app-b
running in the same namespace as your application
{% hint style="danger" %} These applications must already exist in Azure AD in order to be assigned the access policy permissions.
The applications must also have been provisioned through NAIS.
Any application that does not exist in Azure AD will be skipped.
If you do provision Azure AD applications afterwards for any pre-authorized applications and want to assign access policy permissions to these, then make sure to re-deploy your application to provision the correct permissions. {% endhint %}
See the NAV Security Guide for NAV-specific usage.
Otherwise, depending on your application and its intended usage, see the Microsoft identity platform documentation.
Provisioning an Azure AD application will always produce a Secret
resource that is automatically
mounted to the pods of your application.
The secret should be available as files at
/var/run/secrets/nais.io/azure
as well as environment variables.
The following describes the contents of the aforementioned secret.
Azure AD client ID. Unique ID for the application in Azure AD.
Example value:
e89006c5-7193-4ca3-8e26-d0990d9d981f
Azure AD client secret, i.e. password for authenticating the application to Azure AD.
Example value:
b5S0Bgg1OF17Ptpy4_uvUg-m.I~KU_.5RR
Private JWKS, i.e. containing a JWK with the private RSA key for creating signed JWTs when authenticating to Azure AD with a certificate.
Example value:
{
"keys": [
{
"use": "sig",
"kty": "RSA",
"kid": "jXDxKRE6a4jogcc4HgkDq3uVgQ0",
"n": "xQ3chFsz...",
"e": "AQAB",
"d": "C0BVXQFQ...",
"p": "9TGEF_Vk...",
"q": "zb0yTkgqO...",
"dp": "7YcKcCtJ...",
"dq": "sXxLHp9A...",
"qi": "QCW5VQjO...",
"x5c": [
"MIID8jCC..."
],
"x5t": "jXDxKRE6a4jogcc4HgkDq3uVgQ0",
"x5t#S256": "AH2gbUvjZYmSQXZ6-YIRxM2YYrLiZYW8NywowyGcxp0"
}
]
}
A JSON string. List of names and client IDs for the valid (i.e. those that exist in Azure AD) applications defined in
spec.accessPolicy.inbound.rules[]
.
Example value:
[
{
"name": "dev-gcp:othernamespace:app-a",
"clientId": "381ce452-1d49-49df-9e7e-990ef0328d6c"
},
{
"name": "dev-gcp:aura:app-b",
"clientId": "048eb0e8-e18a-473a-a87d-dfede7c65d84"
}
]
The well-known URL with the tenant for which the Azure AD application resides in.
Example value:
https://login.microsoftonline.com/77678b69-1daf-47b6-9072-771d270ac800/v2.0/.well-known/openid-configuration
Your application's Azure AD client ID is available at multiple locations:
- The environment variable
AZURE_APP_CLIENT_ID
, available inside your application at runtime. - The Azure Portal.
- In the Kubernetes resource -
kubectl get azureapp <app-name> -o json | jq '.status.clientId'
{% hint style="warning" %} This feature is only available for applications in team namespaces. {% endhint %}
Migrating from existing infrastructure-as-code (IaC) solution
- Declarative provisioning, straight from your application's
nais.yaml
- No longer dependent on manual user approvals in multiple IaC repositories
- No longer dependent on Vault
- Credentials are rotated on every deploy, completely transparent to the application. This ensures that credentials are fresh and lessens the impact in the case of exposure.
- The exact same feature is present in the GCP clusters, which simplifies migration.
In general, the Azure AD application provisioned through NAIS are entirely new, unique instances with new client IDs and should be treated as such.
We've initially opted to use a single tenant (nav.no
) to reduce confusion for users in terms of user accounts and logins.
However, this is not final.
We may add support for using the development tenant as used in the existing IaC solution if this is a need that is desired.
Do note that the same application in different clusters will be different, unique Azure AD applications, with each having their own client IDs and access policies.
The Azure AD application is automatically configured with sane defaults, with most other common options
available to be configured through nais.yaml
.
Thus, we've opted to not grant owner access to any of the team's members.
Any other use cases not covered is manually handled as of now, but this may change as needs arise.
There are a couple of pitfalls and gotchas you ought to avoid if your existing application has defined a list of pre-authorized applications:
{% hint style="danger" %} 1. Referencing Azure AD applications provisioned through IaC from an application provisioned through NAIS
Azure AD applications provisioned through NAIS are not able to reference existing Azure AD applications provisioned through the existing IaC solution. {% endhint %}
{% hint style="warning" %} 2. Referencing this Azure AD application from an application provisioned through IaC
An existing application provisioned through IaC can reference this Azure AD application by using the naming scheme as defined in getting started. {% endhint %}
Migrating an existing stack of applications should therefore be done in the following order:
- Enable provisioning for all applications in all relevant clusters, but do not use the new credentials.
- Find the relevant client IDs and prepare your applications to reference these instead of the previous ones.
- Prepare your application to use the new credentials instead of the previous ones.
- Deploy to development; ensure that everything works as expected.
- Repeat step 4 for production.