azure-ad-sso

Azure AD SSO Integration Skill

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "azure-ad-sso" with this command: npx skills add julianobarbosa/claude-code-skills/julianobarbosa-claude-code-skills-azure-ad-sso

Azure AD SSO Integration Skill

Overview

This skill provides comprehensive guidance for implementing Azure AD (Entra ID) OAuth2/OIDC Single Sign-On for applications deployed on Kubernetes clusters, including access restriction by Azure AD groups.

Quick Reference

Supported Applications

Application Provider Redirect URI Pattern Group Sync

DefectDojo azuread-tenant-oauth2

/complete/azuread-tenant-oauth2/

Yes

Grafana azuread

/login/azuread

Yes

ArgoCD microsoft (Dex) /api/dex/callback

Yes

Harbor oidc

/c/oidc/callback

Yes

SonarQube saml or oidc

/oauth2/callback/saml

Yes

OAuth2 Proxy azure

/oauth2/callback

Yes

Keycloak oidc

/realms/{realm}/broker/azure/endpoint

Yes

Authentication Flow Decision

┌─────────────────────────────────────────────────────────────────┐ │ Access Control Decision │ ├─────────────────────────────────────────────────────────────────┤ │ │ │ Q: Who should access this application? │ │ │ │ ├─ Everyone in tenant ──► appRoleAssignmentRequired=false │ │ │ │ │ └─ Specific groups ────► appRoleAssignmentRequired=true │ │ + Assign groups to Enterprise App │ │ │ └─────────────────────────────────────────────────────────────────┘

Implementation Workflow

Phase 1: Azure AD App Registration

1. Create App Registration

APP_NAME="<application>-<environment>" REDIRECT_URI="https://<app-domain>/complete/<provider>/"

APP_ID=$(az ad app create
--display-name "$APP_NAME"
--sign-in-audience "AzureADMyOrg"
--web-redirect-uris "$REDIRECT_URI"
--query appId -o tsv)

echo "Application (client) ID: $APP_ID"

2. Get Tenant ID

TENANT_ID=$(az account show --query tenantId -o tsv) echo "Directory (tenant) ID: $TENANT_ID"

3. Create Client Secret

SECRET=$(az ad app credential reset
--id $APP_ID
--append
--years 1
--query password -o tsv)

echo "Client Secret: $SECRET" # Save immediately!

Phase 2: Enable Group Claims

Enable security group claims in tokens

az ad app update --id $APP_ID --set groupMembershipClaims=SecurityGroup

Add Group.Read.All permission (delegated)

az ad app permission add
--id $APP_ID
--api 00000003-0000-0000-c000-000000000000
--api-permissions 5f8c59db-677d-491f-a6b8-5f174b11ec1d=Scope

Grant admin consent

az ad app permission admin-consent --id $APP_ID

Phase 3: Restrict Access by Group (CRITICAL)

Get Service Principal object ID

SP_ID=$(az ad sp list --filter "appId eq '$APP_ID'" --query "[0].id" -o tsv)

Enable user assignment requirement

az ad sp update --id $SP_ID --set appRoleAssignmentRequired=true

Get the group ID to restrict access

GROUP_ID=$(az ad group show --group "G-Usuarios-<App>-Admin" --query id -o tsv)

Assign group to the application (only these users can login)

az rest --method POST
--uri "https://graph.microsoft.com/v1.0/servicePrincipals/$SP_ID/appRoleAssignments"
--headers "Content-Type=application/json"
--body "{ "principalId": "$GROUP_ID", "principalType": "Group", "appRoleId": "00000000-0000-0000-0000-000000000000", "resourceId": "$SP_ID" }"

Phase 4: Store Secret in Key Vault

az keyvault secret set
--vault-name "<keyvault-name>"
--name "<app>-azuread-client-secret"
--value "$SECRET"

Secret Management

SecretProviderClass Template

apiVersion: secrets-store.csi.x-k8s.io/v1 kind: SecretProviderClass metadata: name: <app>-secrets namespace: <namespace> spec: provider: azure parameters: usePodIdentity: "false" useVMManagedIdentity: "true" userAssignedIdentityID: "<managed-identity-client-id>" keyvaultName: "<keyvault-name>" tenantId: "<azure-tenant-id>" objects: | array: - | objectName: <app>-azuread-client-secret objectType: secret objectAlias: AZURE_AD_CLIENT_SECRET secretObjects: - secretName: <app>-azure-ad type: Opaque data: - objectName: AZURE_AD_CLIENT_SECRET key: client-secret

Pod Volume Mount

volumes:

  • name: secrets-store csi: driver: secrets-store.csi.k8s.io readOnly: true volumeAttributes: secretProviderClass: "<app>-secrets"

volumeMounts:

  • name: secrets-store mountPath: "/mnt/secrets-store" readOnly: true

Application Configurations

DefectDojo

Enable SSO

extraEnv:

  • name: DD_SOCIAL_AUTH_AZUREAD_TENANT_OAUTH2_ENABLED value: "True"
  • name: DD_SOCIAL_AUTH_AZUREAD_TENANT_OAUTH2_KEY value: "<client-id>"
  • name: DD_SOCIAL_AUTH_AZUREAD_TENANT_OAUTH2_TENANT_ID value: "<tenant-id>"
  • name: DD_SOCIAL_AUTH_AZUREAD_TENANT_OAUTH2_SECRET valueFrom: secretKeyRef: name: defectdojo key: DD_SOCIAL_AUTH_AZUREAD_TENANT_OAUTH2_SECRET

Group sync

  • name: DD_SOCIAL_AUTH_AZUREAD_TENANT_OAUTH2_GET_GROUPS value: "True"
  • name: DD_SOCIAL_AUTH_AZUREAD_TENANT_OAUTH2_CLEANUP_GROUPS value: "True"
  • name: DD_SOCIAL_AUTH_AZUREAD_TENANT_OAUTH2_GROUPS_FILTER value: "^G-Usuarios-DefectDojo-.*"

CRITICAL: For apps behind reverse proxy

  • name: DD_SECURE_PROXY_SSL_HEADER value: "True"

Grafana

grafana.ini: auth.azuread: enabled: true name: Azure AD allow_sign_up: true client_id: "<client-id>" client_secret: "${GF_AUTH_AZUREAD_CLIENT_SECRET}" scopes: openid email profile auth_url: https://login.microsoftonline.com/&#x3C;tenant-id>/oauth2/v2.0/authorize token_url: https://login.microsoftonline.com/&#x3C;tenant-id>/oauth2/v2.0/token allowed_groups: "<admin-group-id> <viewer-group-id>" role_attribute_path: contains(groups[*], '<admin-group-id>') && 'Admin' || 'Viewer'

ArgoCD (via Dex)

configs: cm: dex.config: | connectors: - type: microsoft id: microsoft name: Azure AD config: clientID: "<client-id>" clientSecret: $dex.azure.clientSecret tenant: "<tenant-id>" redirectURI: https://<argocd-domain>/api/dex/callback groups: - <admin-group-id> rbac: policy.csv: | g, <admin-group-id>, role:admin

Harbor

externalURL: https://harbor.&#x3C;domain> core: oidc: name: "azure" endpoint: "https://login.microsoftonline.com/&#x3C;tenant-id>/v2.0" clientId: "<client-id>" clientSecret: "<from-secret>" scope: "openid,profile,email" groupsClaim: "groups" adminGroup: "<admin-group-id>" autoOnboard: true

Troubleshooting

Error Reference

Error Code Description Solution

AADSTS50011 Reply URL mismatch Verify exact redirect URI including trailing slash

AADSTS50105 User not assigned Add user/group to Enterprise App assignments

AADSTS700016 App not found Check client ID and tenant ID

AADSTS7000218 Secret expired Rotate secret in Key Vault, restart pods

AADSTS90102 Invalid redirect_uri Check DD_SECURE_PROXY_SSL_HEADER=True for reverse proxy

AADSTS65001 Consent not granted Run az ad app permission admin-consent

Common Issues

Malformed redirect_uri (Django apps behind proxy)

Symptom: redirect_uri=https,%20https://...

Root cause: DD_SECURE_PROXY_SSL_HEADER set incorrectly

Fix:

  • name: DD_SECURE_PROXY_SSL_HEADER value: "True" # NOT "HTTP_X_FORWARDED_PROTO,https"

Groups not syncing

Verify group claims enabled

az ad app show --id <app-id> --query groupMembershipClaims

Check API permissions

az ad app permission list --id <app-id>

Verify group exists and user is member

az ad group member check --group "<group-name>" --member-id "<user-object-id>"

Secret not syncing from Key Vault

Check SecretProviderClass

kubectl describe secretproviderclass <name> -n <namespace>

Check CSI driver pods

kubectl get pods -n kube-system | grep secrets-store

Check managed identity access

az keyvault show --name <vault> --query properties.accessPolicies

Diagnostic Commands

Test OAuth redirect

curl -sS -k -D - -o /dev/null "https://<app>/login/<provider>/" 2>&1 | grep -i location

Check environment variables in pod

kubectl exec -n <ns> deploy/<app> -c <container> -- env | grep -i azure

Decode JWT token (after login, from browser dev tools)

Use https://jwt.io to decode and verify claims

Security Best Practices

  • Never hardcode secrets - Always use Key Vault + CSI Driver

  • Use managed identities - Avoid service principal credentials

  • Restrict access by group - Enable appRoleAssignmentRequired=true

  • Rotate secrets - Set calendar reminders before expiration

  • Use HTTPS only - All redirect URIs must use HTTPS

  • Single tenant - Never use multi-tenant for internal apps

  • Audit logging - Enable Azure AD sign-in logs

Environment Reference

Environment Key Vault Managed Identity Tenant ID

cafehyna-dev kv-cafehyna-dev-hlg

f1a14a8f-6d38-40a0-a935-3cdd91a25f47

3f7a3df4-f85b-4ca8-98d0-08b1034e6567

cafehyna-hub kv-cafehyna-default

f1a14a8f-6d38-40a0-a935-3cdd91a25f47

3f7a3df4-f85b-4ca8-98d0-08b1034e6567

cafehyna-prd kv-cafehyna-prd

f1a14a8f-6d38-40a0-a935-3cdd91a25f47

3f7a3df4-f85b-4ca8-98d0-08b1034e6567

Detailed Reference

For complete implementation examples:

  • references/azure-ad-sso-guide.md - Full guide with manifests

  • references/app-configs.md - Application-specific configurations

  • references/troubleshooting.md - Extended troubleshooting guide

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

Coding

obsidian-vault-management

No summary provided by upstream source.

Repository SourceNeeds Review
Coding

zabbix

No summary provided by upstream source.

Repository SourceNeeds Review
Coding

neovim

No summary provided by upstream source.

Repository SourceNeeds Review
Coding

obsidian

No summary provided by upstream source.

Repository SourceNeeds Review