Skip to content

Kubernetes Operator for automated registration of Azure AD applications

License

Notifications You must be signed in to change notification settings

nais/azurerator

Repository files navigation

azurerator

Azurerator is a Kubernetes cluster operator for automated registration and lifecycle management of Azure Active Directory applications.

This specific implementation is tailored towards managing Azure AD applications within a single tenant for use in Web APIs, i.e. both application and user authentication and authorization.

For NAIS end-users

See https://doc.nais.io/security/auth/azure-ad

CRD

The operator introduces a new Kind AzureAdApplication (shortname azureapp), and acts upon changes to resources of this kind.

See the spec in liberator for details.

An example resource is available in config/samples/azureadapplication.yaml.

Lifecycle

overview

See lifecycle for details.

Usage

Installation

make install

Azure AD Setup

You will need the credentials for an Azure AD application with the following Application API permissions for Microsoft Graph:

  • Application.ReadWrite.All or Application.ReadWrite.Owned
    • If you use Application.ReadWrite.Owned, Azurerator will only be able to manage applications and service principals that it has created. It will no longer be able to process these resources if removed as an owner, unless the Application.ReadWrite.All permission is granted.
  • DelegatedPermissionGrant.ReadWrite.All
  • GroupMember.Read.All (optional, only needed for the groups-assignment feature)
  • Policy.Read.All (optional, only needed for the claims-mapping policies feature)
  • CustomSecAttributeAssignment.ReadWrite.All (optional, only needed for the custom security attributes feature)

Finally, in order to ensure that Azurerator may pre-approve delegated API permissions for the managed applications, you will need to find and configure the azure.permissiongrant-resource-id configuration flag.

This ID is the Object ID of an Azure AD Enterprise Application that is unique to each tenant.

You will find this under either the name of GraphAggregatorService or Microsoft Graph. Look for an Enterprise Application that has an Application ID equal to 00000003-0000-0000-c000-000000000000.

Configuration

Azurerator can be configured using either command-line flags or equivalent environment variables (i.e. -, . -> _ and uppercase), with AZURERATOR_ as prefix. E.g.:

azure.auth.client-id -> AZURERATOR_AZURE_AUTH_CLIENT_ID

The following flags are available:

--azure.auth.client-id string                                       Client ID for Azure AD authentication
--azure.auth.client-secret string                                   Client secret for Azure AD authentication
--azure.delay.between-modifications duration                        Delay between modification operations to the Graph API. (default 3s)
--azure.features.app-role-assignment-required.enabled               Enable 'appRoleAssignmentRequired' for service principals.
--azure.features.claims-mapping-policies.id string                  Claims-mapping policy ID for custom claims mapping
--azure.features.claims-mapping-policies.enabled                    Assign custom claims-mapping policies to a service principal
--azure.features.custom-security-attributes.enabled                 Set custom security attributes on service principals (attribute set of 'Applications':'ManagedBy':'NAIS')  
--azure.features.cleanup-orphans.enabled                            Enable cleanup of orphaned resources.
--azure.features.group-membership-claim.default string              Default group membership claim for Azure AD apps. (default "ApplicationGroup")
--azure.features.groups-assignment.all-users-group-id string        Group ID that contains all users in the tenant. Assigned to all application by default unless overridden by user in the custom resource.
--azure.features.groups-assignment.enabled                          Assign groups to applications
--azure.pagination.max-pages int                                    Max number of pages to fetch when fetching paginated resources from the Graph API. (default 1000)
--azure.permissiongrant-resource-id string                          Object ID for Graph API permissions grant ('GraphAggregatorService' or 'Microsoft Graph' in Enterprise Applications under 'Microsoft Applications')
--azure.tenant.id string                                            Tenant ID for Azure AD
--azure.tenant.name string                                          Alias/name of tenant for Azure AD
--cluster-name string                                               The cluster in which this application should run
--controller.context-timeout duration                               Context timeout for the reconciliation loop in the controller. (default 5m0s)
--kafka.brokers strings                                             Comma-separated list of Kafka brokers, HOST:PORT. (default [localhost:9092])
--kafka.enabled                                                     Toggle for enabling Kafka to allow synchronization of events between Azurerator instances.
--kafka.max-processing-time duration                                Maximum processing time of Kafka messages. (default 10s)
--kafka.retry-interval duration                                     Retry interval for Kafka operations. (default 5s)
--kafka.tls.ca-path string                                          Path to Kafka TLS CA certificate.
--kafka.tls.certificate-path string                                 Path to Kafka TLS certificate.
--kafka.tls.enabled                                                 Use TLS for connecting to Kafka.
--kafka.tls.private-key-path string                                 Path to Kafka TLS private key.
--kafka.topic string                                                Name of the Kafka topic that Azurerator should use. (default "azurerator-events")
--leader-election.enabled                                           Leader election toggle.
--leader-election.namespace string                                  Leader election namespace.
--metrics-address string                                            The address the metric endpoint binds to. (default ":8080")
--secret-rotation.cleanup                                           Clean up unused credentials in Azure AD after rotation. (default true)
--secret-rotation.max-age duration                                  Maximum duration since last rotation before triggering rotation on next reconciliation, regardless of secret name being changed. (default 2880h0m0s)
--validations.tenant.required                                       If true, will only process resources that have a tenant defined in the spec

At minimum, the following configuration should be provided:

  • azure.auth.client-id
  • azure.auth.client-secret
  • azure.permissiongrant-resource-id
  • azure.tenant.id
  • azure.tenant.name
  • cluster-name

Equivalently, one can specify these properties using JSON, TOML, YAML, HCL, envfile and Java properties config files. Azurerator looks for a file named azurerator.<ext> in the directories [., /etc/azurerator/].

Example configuration in YAML:

# ./azurerator.yaml

azure:
  auth:
    client-id: ""
    client-secret: ""
  tenant:
    id: ""
    name: "local.test" # e.g. your domain
  permissiongrant-resource-id: ""
cluster-name: minikube

Development

After configuration, assuming you have a Kubernetes cluster running locally (e.g. using minikube):

ulimit -n 4096  # for controller-gen
make run # starts the controller

# in another terminal, apply an AzureAdApplication resource
make sample

Kubebuilder is required for running the tests. Install with make kubebuilder.

Verifying the Azurerator image and its contents

The image is signed "keylessly" (is that a word?) using Sigstore cosign. To verify its authenticity run

cosign verify \
--certificate-identity "https://github.com/nais/azurerator/.github/workflows/main.yml@refs/heads/master" \
--certificate-oidc-issuer "https://token.actions.githubusercontent.com" \
ghcr.io/nais/azurerator@sha256:<shasum>

The images are also attested with SBOMs in the CycloneDX format. You can verify these by running

cosign verify-attestation --type cyclonedx \
--certificate-identity "https://github.com/nais/azurerator/.github/workflows/main.yml@refs/heads/master" \
--certificate-oidc-issuer "https://token.actions.githubusercontent.com" \
ghcr.io/nais/azurerator@sha256:<shasum>

About

Kubernetes Operator for automated registration of Azure AD applications

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Languages