Skip to content
CAMPUX Cloud Bootcamp Phase Four · Class Thirty-One
Phase Four — Operate, Secure & AI
4 drills · 2 situations · Part I of II
Security & DevSecOps
Class Thirty-One · Part I

Secrets & Identity

Store credentials in a vault, give each workload only the access it needs, and review human and pipeline privileges before they accumulate.

Phase Four · Operate, Secure, AI · Class 31 · Part A · 14 min · Assumes Class 31 and Class 9

After this you can protect necessary secrets, use supported identity-based access, and verify credential rotation and deployment scope.

New to this? Read Class 31 and Class 9 first. Already done them, or know the material? Carry on.

§1

Key Vault — one place for the dangerous strings

The warehouse app stops connecting after a password change. Ada finds three copies of the old connection string: one in a file, one in deployment configuration, and one in a teammate’s notes. “Which one does the running app use?” she asks. Put a necessary secret in a controlled store, give the app permission to retrieve it, and verify how it receives the new version. Where the target supports identity-based access, investigate removing the password altogether. A vault helps control a secret; it does not stop code from logging the value after retrieval.

Key Vault
A service for storing secrets, keys, and certificates. In an Azure RBAC vault, data-plane roles control who reads or changes their values. Send audit events to a chosen destination with diagnostic settings if the team needs retained access logs; this lab does not configure logging.

First, choose the vault's permission model. In an Azure RBAC vault, Key Vault Secrets User reads secret values and Key Vault Secrets Officer manages them; assign the narrowest needed role and scope.1 Second, give an App Service or Container App a managed identity and a Key Vault reference when the platform supports it. The platform retrieves the value, but the application still receives that secret as configuration and must avoid logging it. Rotation is not instant everywhere: confirm each service's refresh behavior and test that it picked up the new version.

Play

Play it through

Three minutes, two gates. Block a supported credential before it reaches GitHub, then require a pull-request scan before merging. The game also explains what to do if a value was already exposed.

§2

Least privilege in pipelines — the audit

Phase Three built machinery with real power: identities that deploy to production, tokens that write to your repositories, runners that execute whatever workflows say. This section is the audit you now know enough to run — four questions, asked of every pipeline, each one a callback:

# the pipeline least-privilege audit — run it quarterly
1. What can each deployment identity reach?    (Class 8)
   → Scope the required role to the resources it deploys.
2. Which runs can assume that identity?        (Class 23)
   → Review the federated credential's repo, ref, and environment claims.
3. What can the GITHUB_TOKEN do?               (Class 24)
   → Default to read access; grant write only to jobs that need it.
4. Who reviews the files that grant all this?  (Class 22)
   → Protect workflow changes with owners and required review.

Power accumulates; audits subtract.

Figure — The four gates of the pipeline audit
gate 01 · class 8 what can it reach? Contributor on its own resource group — never the subscription gate 02 · class 23 who can become it? subject claims — environment:production, never pull_request gate 03 · class 24 what can the token do? contents: read at the top; more only where earned gate 04 · class 22 who reviews the grants? .github/ behind CODEOWNERS + required review privilege only drifts upward — walk the four gates quarterly
Use these four questions for each deployment identity: what it can change, which workflow runs can assume it, what the workflow token can write, and who must review changes to the workflow. The diagram shows a sample policy; the exact resource scope and review rules depend on the deployment. Verify the current assignments and repository settings rather than assuming a posture score covers them.

Run this review after workflow, identity, or deployment-scope changes and on a recurring schedule. Start from the live Azure role assignments and GitHub settings, not from a saved diagram. Defender for Cloud may surface some broad assignments, but it does not replace checking the federated credential subject, token permissions, and branch protections. Record any exception with its owner and expiry, then test that the workflow can still deploy with the narrower permissions.

Later · §3

Least privilege that expires

Class Eight gave you least privilege in space: who may touch what, scoped to the narrowest resource that still lets the work happen. It said nothing about time. The Owner role granted at 2am to fix an incident is still Owner at noon the following Tuesday, and the month after that, quietly attached to an account nobody remembers elevating. Standing privilege is the liability the §2 audit keeps finding, because an account that is always an administrator is always worth stealing — and the attacker who lands on it inherits every hour of access it was never using.

Privileged Identity Management (PIM) can make a high-privilege role eligible rather than permanently active. The user activates it when needed; the configured policy can require justification, MFA, approval, and a limited duration. An eligible role still creates a path to privilege, so protect the account and review who remains eligible. PIM requires appropriate licensing; check the current licensing and activation policy before designing an incident response around it.

Eligible vs active
Eligible means the user may request or perform activation under the configured policy. Active means the role is currently usable. Eligibility reduces standing access but still needs account protection and review.
Activation
The act of claiming an eligible role: justification, a self-expiring window, and — for the roles that warrant it — approval and MFA at the moment of use, which is exactly when proof of identity is worth demanding.
Access reviews
A reviewer checks whether each assignment is still needed. Removal depends on how the review is configured and completed; do not assume an unused grant expires automatically.
Break-glass accounts
Two excluded emergency accounts, cloud-only, outside PIM and Conditional Access, stored offline and heavily alerted — the way back in the day the identity system itself locks you out. Guard them like the spare key they are.

The pipeline audit limits workload identities; PIM limits standing human privilege. For each, ask what an attacker could do with the account now, what extra steps could grant more access, and whether those steps are monitored.

Watch · Microsoft Learn

The official Key Vault guide

The vault page before Lab 1
Microsoft Learn · Docs

About Azure Key Vault
learn.microsoft.com/azure/key-vault/general/overview

Lab 1 · Key Vault

Store a secret, and feel the door work both ways

~15 minutes plus role propagation · Azure Cloud Shell Bash · one disposable resource group

Use a disposable training value, never a real password. Create a vault with Azure RBAC permissions, observe a data-plane denial, then grant a scoped role and retry. You need permission to create Azure role assignments for the grant step; ask your subscription administrator if you do not have it.

  1. In Cloud Shell Bash, choose a unique vault name and create it in your intended subscription:

    az account show --query '{name:name,subscriptionId:id}' -o table
    VAULT_NAME="campux-kv-<unique-suffix>"
    az group create --name rg-vault-lab --location eastus
    az keyvault create --name "$VAULT_NAME" \
      --resource-group rg-vault-lab \
      --enable-rbac-authorization true
    What to notice: vault names must be globally unique. The RBAC flag chooses Azure role assignments for secret access. Creating the vault is a control-plane operation; it does not automatically give your account a data-plane secret role.
  2. Try to store a harmless training value before granting a secret role:

    az keyvault secret set --vault-name "$VAULT_NAME" \
      --name training-value --value "not-a-real-credential" --output none
    Expected: a Forbidden result if your account has no data-plane role. If it succeeds, inspect your existing role assignments rather than treating success as a vault failure. A real credential must never be pasted into the terminal or a lesson.
  3. If you have role-assignment permission, grant your signed-in user the data-plane role at this vault only, then retry:

    az role assignment create \
      --assignee $(az ad signed-in-user show --query id -o tsv) \
      --role "Key Vault Secrets Officer" \
      --scope $(az keyvault show --name "$VAULT_NAME" \
          --query id -o tsv)
    # wait for role propagation, then re-run step 2
    What to notice: this grant requires Microsoft.Authorization/roleAssignments/write, held by roles such as Owner, User Access Administrator, or Key Vault Data Access Administrator with its restricted scope. Grant only at the vault scope. A runtime that reads secrets normally needs Secrets User, not Secrets Officer.
  4. Read its metadata without printing the value, then remove the lab resources:

    az keyvault secret show --vault-name "$VAULT_NAME" \
      --name training-value --query '{name:name,id:id}' -o json
    az keyvault secret list --vault-name "$VAULT_NAME" -o table
    az group delete --name rg-vault-lab --yes
    az keyvault purge --name "$VAULT_NAME"   # a deleted vault is soft-deleted and keeps its name until purged
    The lesson: the successful secret show call confirms that your data-plane role can read the object. This lab has not configured retained Key Vault audit logs or connected an application. Confirm asynchronous resource-group deletion afterward. A soft-deleted vault may retain its name during the recovery window.
Class Thirty-One · Part I

Examination

Four drills, then two situations. The situations have no marking scheme — write your answer before you reveal the reasoning, or the exercise is worthless. Nothing is stored; this is between you and the page.

Drill 01Recall · vault
What is the recommended way for a Container App to read a database password from Key Vault?
Marked

B. The managed identity authenticates the app to Azure, the scoped Secrets User role permits reading the vault's secret values, and the reference tells the platform which value to retrieve. The application still receives the value and must not log it. Rotation has a service-specific refresh delay; verify the new version reached the running app. A recreates a stored-credential problem, C leaves a copy in app configuration, and D grants far too much access.

Drill 02Recall · vault
In Lab 1, you created a vault and were immediately denied when storing a secret in it. Why?
Marked

C. In an Azure RBAC vault, a control-plane role such as Key Vault Contributor does not by itself grant permission to read secret values. A separate data-plane role is needed. The vault's permission model matters: a legacy access-policy vault has different administration risks, so inspect the model before making a blanket claim about every vault.

Drill 03Spot the error
This configuration review is about to be approved. One line is a serious mistake. Which?
# review: storefront app configuration
1.  App runs on Container Apps with a system-assigned
    managed identity.
2.  App settings:
      DB_CONNECTION = "Server=campux-sql;User=app;
                       Password=training-only-example"
3.  The identity holds Key Vault Secrets User on
    campux-kv-storefront.
4.  Deployment is via the Class 23 OIDC pipeline with
    environment approval on production.
Marked

Line two. The app already has a managed identity and a scoped vault role, but the example still copies a credential into its configuration. Someone who can read or export that configuration, a deployment template, or related state may receive the value. That access is role-dependent; ordinary portal visibility alone does not prove a person can read it.

Replace the literal value with a Container Apps secret whose source is a Key Vault reference, then bind the app's environment variable to that secret. Rotate the old credential if it was exposed, and test that the running app receives the replacement after the platform refreshes it. A and C describe supported identity and read-only access; D is a valid production review gate.

Drill 04Select three
Which three describe what Privileged Identity Management changes about standing privilege?
Marked

Options 1, 2, and 4. Eligibility keeps a role inactive until activation, and the activation can have a time limit and extra requirements. Access reviews let a reviewer decide whether eligibility remains justified; removal depends on the review configuration. PIM does not review a pipeline's GitHub token and federated credential, and emergency access accounts need a separate, tested procedure. Eligibility reduces standing privilege but does not make a compromised account harmless.

Situation 01Write before you reveal
A teammate pushes back on the vault migration: "Our apps run in a private VNet behind Class 14's private endpoints. Nothing external can reach them — why are we spending a sprint moving settings into Key Vault?" How do you answer?
The network boundary is real. List what crosses it anyway — starting with people.
Reasoning

The network and vault answer different questions. A private endpoint restricts network paths to a service. It does not decide who may export application settings, read deployment state, or use a copied credential somewhere else. Check the roles that can read the current configuration and the places that configuration has been copied.

Moving the value to Key Vault lets the team scope data-plane reads to an identity and control rotation centrally. Enable diagnostic settings if retained vault access events are needed. The running app will still receive the secret, so its code and logs remain in the threat model. Rotate any value already exposed, then test the reference and refresh behavior before removing the old configuration.

Show the difference with one request. “The private route gets our app to the vault; its identity still needs permission to read this secret. We will test both separately.” Then check the app resolves its reference without logging the value. A vault network error and an authorization error call for different corrections. Moving an already copied password does not invalidate the copy: rotation closes that route.

Situation 02Write before you reveal
An on-call engineer asks for standing Owner on the production subscription "so incidents get fixed faster" instead of activating through PIM every time. How do you respond, and what do you offer instead?
Time the actual friction before arguing about it. Then solve the friction, not the control.
Reasoning

Concede the real cost, then name what standing Owner does not buy. Activation adds seconds — a justification, maybe an approver, an MFA prompt — at the exact moment an incident is burning money, and waving that away as imaginary loses the engineer's trust before the conversation starts. But standing Owner does not buy speed in the case that matters most: the day the credential itself is the incident. A standing Owner grant is active every hour of every day whether anyone is on call or not, which makes it the single biggest thing an attacker can steal from the estate — and it buys that risk in exchange for saving a few seconds on the rare incident that actually needs it.

Offer the fix that solves the friction without buying the risk. Configure the on-call role's PIM activation to skip the approval step — self-activate, no second human in the loop — while keeping the time box and the MFA prompt, since the approver is usually the slow part, not the activation itself. A four-hour window covers nearly every incident and expires before anyone forgets it is on. If a specific class of incident is genuinely too urgent for even a self-service activation, that is what a break-glass account exists for, not a standing Owner grant — and using one is loud, alerted, and reviewed the next morning.

Close on the real disagreement. The objection was never about privilege; it was about speed. PIM's whole design already lets you buy speed with a configuration change — skip the approver, widen the window — in a way no standing grant can match on safety, because every one of those changes still leaves a record of who activated what, and when.

Examination record · first attempt
0/4
Class Thirty-One · Part I · Complete
Retain this much

Five things worth carrying out of this class

  1. Key Vault can store secrets, keys, and certificates. Choose the permission model, grant a data-plane role at the right scope, and configure diagnostic settings if retained audit events are required.
  2. For supported services, a managed identity plus scoped Secrets User and a Key Vault reference can keep a secret out of copied application settings. The app still receives the value; test rotation and refresh.
  3. Review four parts of every deployment workflow: the Azure role's scope, who can assume it, what its GitHub token can do, and who reviews changes to the workflow. Repeat after changes and on a schedule.
  4. PIM can keep a human role eligible instead of always active. Activation requirements and expiry depend on the configured policy; review eligible users as well as active ones.
  5. For a leaked credential, rotate or revoke first, then remove copies and improve the controls that failed. A vault and scanner do not undo exposure that already occurred.
Notes
  1. Key Vault's older access model — vault access policies — still exists and still guards many production vaults you will inherit; RBAC authorization is the recommended mode for new vaults and the one this class teaches. Know both names for interviews, and when you meet a policy-mode vault, treat migrating it as ordinary maintenance rather than an emergency. Also worth knowing: soft delete and purge protection, which make vault contents survive accidental — and malicious — deletion. ↩