13.2 Service Connections, Workload Identity & Personal Access Tokens
Key Takeaways
- Azure DevOps Service Connections securely store and inject external credentials into pipeline execution contexts, supporting fine-grained pipeline authorization and cross-project sharing.
- Workload Identity Federation (OpenID Connect / OIDC) establishes a secretless trust relationship between external CI/CD platforms (Azure DevOps or GitHub Actions) and Microsoft Entra ID using short-lived JWT tokens.
- OIDC eliminates static client secrets, certificates, expiration calendars, and rotation vulnerabilities by exchanging an ephemeral token issued by a trusted OIDC identity provider.
- Personal Access Tokens (PATs) in Azure DevOps should be tightly scoped, enforced with short expirations (e.g., 30-90 days), governed by Entra Conditional Access policies, and restricted from administrative agent registration.
- GitHub Actions supports multiple authentication primitives: GitHub Apps provide isolated organizational permissions and high rate limits, Fine-Grained PATs offer repository scoping, and the ephemeral GITHUB_TOKEN secures in-workflow operations.
13.2 Service Connections, Workload Identity & Personal Access Tokens
Automated CI/CD pipelines cannot operate in isolation. They must continuously interact with cloud subscriptions, container registries, external version control systems, artifact repositories, and monitoring platforms. Establishing, securing, and governing these external interfaces is central to DevOps pipeline security.
In Azure DevOps, the primary mechanism for abstracting and securing external resource access is the Service Connection. In modern cloud engineering, connecting pipelines to Microsoft Azure has evolved from managing static credentials to implementing Workload Identity Federation via OpenID Connect (OIDC). Additionally, developers and automation agents frequently utilize Personal Access Tokens (PATs) and GitHub authentication tokens, each carrying distinct security boundaries that candidates must navigate on the AZ-400 exam.
1. Azure DevOps Service Connections Architecture
A Service Connection (internally called a Service Endpoint) is an administrative construct configured at the Azure DevOps Project level (Project Settings → Service connections). It stores connection metadata, endpoint URLs, and authentication credentials required to communicate with external services.
┌─────────────────────────────────────────────────────────────────────────────┐
│ Azure DevOps Project Settings: Service Connection Architecture │
│ │
│ ┌───────────────────────────────────────────────────────────────────────┐ │
│ │ Encrypted Secret Store │ │
│ │ (Stores Service Principal Keys, OIDC Trust Config, or API Tokens) │ │
│ └───────────────────────────────────┬───────────────────────────────────┘ │
│ │ Runtime Decryption │
│ ▼ │
│ ┌───────────────────────────────────────────────────────────────────────┐ │
│ │ Pipeline Execution Engine │ │
│ │ • Evaluates Pipeline Permissions (Explicit vs Open Access) │ │
│ │ • Evaluates Approvals & Checks (Business Hours, REST CAB Gates) │ │
│ └───────────────────────────────────┬───────────────────────────────────┘ │
│ │ Injects Ephemeral Credentials │
│ ▼ │
│ ┌───────────────────────────────────────────────────────────────────────┐ │
│ │ Pipeline Job Execution Agent │ │
│ │ (Executes Task using AzureCLI@2, AzureResourceManagerTemplateDeploy) │ │
│ └───────────────────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────────────────┘
Common Service Connection Types
- Azure Resource Manager (ARM): The most critical connection type. Used by tasks such as
AzureCLI@2,AzurePowerShell@5, andAzureResourceManagerTemplateDeployment@3. It authenticates against Microsoft Entra ID to deploy resources to an Azure Subscription or Management Group. - GitHub / GitHub Enterprise: Authenticates Azure Pipelines to external GitHub repositories using OAuth, Personal Access Tokens, or the official Azure Pipelines GitHub App.
- Docker Registry: Connects to container registries (Azure Container Registry, Docker Hub, or private registries) to push/pull container images via
Docker@2tasks. - Kubernetes: Connects to Azure Kubernetes Service (AKS) or generic clusters using Service Account tokens, Kubeconfig, or Azure subscription credentials.
- Generic / REST / SSH: Connects to legacy servers or external webhooks via HTTP basic authentication, API tokens, or SSH private keys.
Security & Authorization Boundaries
- Project Isolation: By default, a Service Connection is strictly isolated to the Azure DevOps project in which it was created. To use the same connection in another project, administrators must explicitly configure Cross-Project Sharing rather than duplicating credentials.
- User Roles on Service Connections:
- Reader: Can view the service connection metadata but cannot use it in pipelines.
- User: Can use the service connection in pipeline YAML definitions.
- Administrator: Can edit connection parameters, delete the endpoint, and manage role permissions.
- Pipeline Permissions (Critical Security Setting):
- Open Access ("Grant access permission to all pipelines"): Any pipeline in the project can consume the connection. This introduces extreme risk: an unreviewed pull request modifying a YAML pipeline could extract or misuse production credentials.
- Restricted Access (Recommended): The connection cannot be used by any pipeline until explicitly authorized by a Service Connection Administrator, or restricted to authorized YAML definitions that have passed formal code review.
2. Workload Identity Federation (OIDC): Secretless Pipeline Authentication
Historically, an Azure Resource Manager Service Connection required either an Entra Service Principal Client Secret (stored in Azure DevOps and manually rotated before expiration) or an X.509 Certificate.
Workload Identity Federation leverages the OpenID Connect (OIDC) standard (RFC 7519 / RFC 7523) to eliminate secrets entirely. It establishes a direct cryptographic trust relationship between the CI/CD platform (Azure DevOps or GitHub Actions) and Microsoft Entra ID.
How OIDC Workload Identity Federation Works
[CI/CD Runner / Agent] ────1. Request OIDC Token (aud, sub)────► [Pipeline Token Service]
│ │
│ 2. Signs JWT with
│ Asymmetric Key
│ │
▼ ▼
[Deployment Step] ─────────3. Exchange JWT Token─────────────► [Microsoft Entra ID]
│ (POST /oauth2/v2.0/token) │
│ 4. Validates:
│ • Issuer URI
│ • Subject Claim
│ • Audience
│ │
▼ ▼
[Deployment Step] ◄────────5. Issues Short-Lived Access Token─── [Microsoft Entra ID]
│ (OAuth 2.0 Bearer Token, ~1 hr)
▼
[ARM Deployment] ──────────6. Authenticates with Bearer Token──► [Azure Subscription]
The Three Trust Parameters
To configure Workload Identity Federation, a Federated Identity Credential is created on the Microsoft Entra Application Registration matching three strict parameters:
- Issuer URL:
- For Azure DevOps:
https://vstoken.dev.azure.com/{OrganizationId} - For GitHub Actions:
https://token.actions.githubusercontent.com
- For Azure DevOps:
- Audience:
- Fixed standard value:
api://AzureADTokenExchange
- Fixed standard value:
- Subject Identifier (
sub):- Azure DevOps Syntax:
sc://<OrganizationName>/<ProjectName>/<ServiceConnectionName> - GitHub Actions Syntax: Scoped to repository, branch, or environment:
- Branch Scope:
repo:<Organization>/<Repository>:ref:refs/heads/main - Environment Scope:
repo:<Organization>/<Repository>:environment:Production - Pull Request Scope:
repo:<Organization>/<Repository>:pull_request
- Branch Scope:
- Azure DevOps Syntax:
Why OIDC is the Industry Standard for AZ-400
- Zero Secret Management: No passwords or certificates exist to create, store, view, or rotate.
- Zero Pipeline Outages: Pipelines never fail due to expired credentials.
- Granular Subject Validation: Microsoft Entra ID will reject authentication requests if the workflow does not run on the designated branch or environment, preventing staging builds from impersonating production identities.
3. Personal Access Tokens (PATs) in Azure DevOps
A Personal Access Token (PAT) is an alternate authentication string acting on behalf of a specific human user account in Azure DevOps. PATs are primarily used for:
- Git command-line operations over HTTPS (
git clone,git push). - Authenticating external tools and scripts against the Azure DevOps REST API.
- Registering self-hosted build agents via
config.cmdorconfig.sh.
Security Vulnerabilities of PATs
- User Impersonation & Blast Radius: A PAT inherits all permissions of the user who generated it. If a Project Collection Administrator generates a PAT with Full Access, anyone who obtains that string possesses full administrative control over the entire Azure DevOps organization.
- Static Persistence: PATs do not support interactive Multi-Factor Authentication (MFA) challenges upon use. Once created, they bypass interactive conditional access prompts.
- Orphaned Automations: If an employee leaves the company and their Microsoft Entra account is deleted or disabled, all PATs generated by that employee immediately stop working, causing catastrophic outages in automated scripts.
PAT Governance & Best Practices
┌─────────────────────────────────────────────────────────────────────────────┐
│ Azure DevOps PAT Governance Checklist │
├─────────────────────────────────────────────────────────────────────────────┤
│ [✔] Enforce Maximum Lifetime: Cap PAT lifespan to 30 or 90 days via Org │
│ Policy (Project Settings -> Policies -> Maximum PAT lifespan). │
│ [✔] Restrict Full Access: Disable creation of 'All scopes' PATs globally. │
│ [✔] Enforce Least-Privilege Scopes: │
│ • For Agent Registration: Scope strictly to 'Agent Pools (Read & Manage)'│
│ • For Git HTTPS: Scope strictly to 'Code (Read & Write)' │
│ • For Release Scripts: Scope strictly to 'Release (Read & Execute)' │
│ [✔] Route Through Entra Conditional Access: Enable Microsoft Entra IP-based │
│ Conditional Access and Device Compliance checks on Azure DevOps. │
│ [✔] Audit Inactive PATs: Regularly revoke unused tokens via Organization │
│ Settings -> Personal Access Tokens audit log. │
└─────────────────────────────────────────────────────────────────────────────┘
4. GitHub Authentication Mechanisms for CI/CD
Modern enterprise DevOps frequently involves integrating Azure with GitHub repositories. Selecting the appropriate GitHub authentication mechanism is heavily tested on the AZ-400 exam.
1. The Ephemeral GITHUB_TOKEN
- Automatically provisioned by GitHub Actions at the start of every workflow job.
- Valid only for the duration of the job; automatically revoked upon job termination.
- Configured with granular permissions via the
permissions:block in the YAML file:name: Release Pipeline on: push: branches: [ main ] permissions: contents: write # Allows creating Git tags and releases pull-requests: write # Allows commenting on PRs id-token: write # MANDATORY for OIDC Workload Identity Federation issues: none # Explicitly denies issue access
2. GitHub Apps (Recommended Enterprise Integration)
- Acts as an independent entity rather than acting on behalf of a specific user account.
- Installed directly on an organization or specific repositories.
- Generates short-lived installation access tokens (valid for 1 hour).
- Boasts significantly higher API rate limits (up to 15,000 requests/hour compared to 5,000/hour for user PATs).
- Ideal for integrating Azure Pipelines with GitHub repositories (Azure Pipelines GitHub App).
3. Personal Access Tokens (Classic vs. Fine-Grained)
- Classic PATs: Legacy tokens scoped account-wide across all repositories. A classic PAT with
reposcope can read and write to every private repository the user has access to. - Fine-Grained PATs: Modern tokens restricted to specific repositories, configured with explicit granular permissions (e.g., read-only on repository contents, no access to secrets), and enforce mandatory expiration dates (maximum 1 year) with organizational approval workflows.
5. Token & Authentication Comparison Matrix
| Authentication Mechanism | Primary Use Case | Credential Lifespan | Management Overhead | Security Posture & Least Privilege |
|---|---|---|---|---|
| Workload Identity Federation (OIDC) | Azure Pipelines & GitHub Actions deploying to Azure | Ephemeral (Short-lived JWT, ~1 hour) | Zero (Secretless, no rotation required) | Maximum: Cryptographically verified subject claim; zero secret storage |
| System-Assigned Managed Identity | Azure compute resources connecting to Azure | Ephemeral (Internal token rotation) | Zero (Managed entirely by Azure) | Maximum: Tied 1:1 to single Azure host lifecycle |
| User-Assigned Managed Identity | Shared compute pools (VMSS) deploying to Azure | Ephemeral (Internal token rotation) | Zero (Managed entirely by Azure) | Maximum: Reusable across resources; independent lifecycle |
| Entra Service Principal (Client Secret) | Legacy external CI/CD tools deploying to Azure | Up to 24 months | High (Must monitor calendar and rotate) | Low: Static password; risk of repo leakage and log exposure |
| Azure DevOps Personal Access Token (PAT) | Git HTTPS, REST API scripts, Agent config | Configurable (Max 1 year, recommended ≤90 days) | Medium (Manual renewal and revocation) | Medium to Low: Inherits full user identity permissions; no MFA on use |
GitHub Ephemeral GITHUB_TOKEN | GitHub Actions interacting with GitHub repo | Ephemeral (Duration of single job) | Zero (Automated generation/cleanup) | High: Scoped per workflow via YAML permissions: block |
| GitHub App Installation Token | Enterprise automation integrating with GitHub | Short-lived (1 hour) | Low (Handled via GitHub App API handshake) | High: Decoupled from users; independent rate limits and scopes |
6. Realistic Exam Scenario & Common Traps
Scenario: Secretless Multi-Stage Deployment Pipeline
Organization: Tailwind Traders maintains an e-commerce platform with source code hosted in GitHub Enterprise and infrastructure deployed to Azure. The security operations team implemented a strict compliance mandate: "No production credentials, certificates, or personal access tokens may be stored in GitHub Secrets or Azure DevOps Variable Groups."
DevOps Implementation:
- The DevOps engineer configures an Azure Active Directory (Entra ID) App Registration named
app-tailwind-deployer. - In Entra ID, the engineer creates a Federated Identity Credential with:
- Issuer:
https://token.actions.githubusercontent.com - Subject:
repo:TailwindTraders/eCommerce:environment:Production - Audience:
api://AzureADTokenExchange
- Issuer:
- In GitHub, an Environment named
Productionis configured with required reviewer approval gates. - In the GitHub Actions workflow YAML, the job sets
permissions: id-token: writeand callsazure/login@v2using the Client ID, Tenant ID, and Subscription ID (which are non-sensitive identifiers, not secrets). - During execution, the GitHub runner exchanges its OIDC token for an ephemeral Entra ID access token valid for 60 minutes, completing the deployment without a single secret stored in GitHub.
Common Exam Traps to Avoid
- Trap: Forgetting
id-token: writein GitHub Actions OIDC workflows. If the workflow YAML omitsid-token: writein thepermissions:block, the GitHub runner cannot request the OIDC JWT token from the GitHub token service, causingazure/loginto fail with an authorization error. - Trap: Believing Service Connection "Open Access" is safe in enterprise projects. Checking "Grant access permission to all pipelines" allows any developer who can create or edit a pipeline to trigger builds that execute commands under that service connection. Production service connections must always enforce restricted pipeline permissions.
- Trap: Using user PATs for production unattended service automation. When the engineer leaves the organization, their Entra identity is deactivated and all automated jobs immediately crash. Unattended automation must use Service Principals or Managed Identities, not human PATs.
A DevOps team manages multi-stage YAML pipelines in Azure DevOps that deploy infrastructure to Microsoft Azure. The Chief Information Security Officer (CISO) mandates that all deployment pipelines must eliminate static client secrets and certificates stored in Azure DevOps to prevent credential leakage and expiration outages. Which Azure Resource Manager Service Connection configuration should the team implement?
An infrastructure engineer needs to automate the registration of self-hosted build agents on on-premises Windows servers using a PowerShell script. What is the most secure method to generate and manage the Personal Access Token (PAT) required for agent pool registration?
A developer configures a GitHub Actions workflow to deploy an application to Azure using OpenID Connect (OIDC) Workload Identity Federation. When the workflow runs on a feature branch named 'feature/login-screen', the deployment fails at the azure/login action with the error: 'AADSTS700213: No matching federated identity record found for present assertion.' The federated credential in Microsoft Entra ID was configured with Subject identifier 'repo:Contoso/App:ref:refs/heads/main'. What is the root cause of this failure?