Chapter 2 of 16 · Human user · Priya

Safe Local Lab and First Login

Operate a disposable Vault lab without committing bootstrap tokens, generated credentials, certificates, or runtime configuration.

Chapter contract

Persona: Human user · PriyaPhase: Human Vault user foundationsEstimated time: 35 minutes

Prerequisites:

Docker with Compose, Vault CLI, jq, curl, OpenSSL, and Python 3.

User-visible outcome:

Priya can use a constrained local identity and reset the lab without exposing bootstrap material.

Learning objectives

Consumer flow

Generated runtime filesstep 1Compose bootstrapstep 2Constrained tokenstep 3Metadata checksstep 4

Ownership boundary

OwnerConsumer-facing responsibility
You ownDefines consumption, validation, reload, and stop-using behavior.
Platform team ownsProvides trusted runtime identity, protected delivery, network, and telemetry.
Vault ownsOperates auth mounts, policies, engines, audit, and recovery.

Core concepts

Dev server

An in-memory teaching server; it is never a production topology.

OIDC login

In a shared environment, Priya proves identity in the browser and Vault maps approved claims to policies. The platform owns OIDC configuration.

Constrained lab token

A finite teaching identity with only the learner policy; it stands in for OIDC without adding an identity provider.

Idempotence

Repeated setup converges instead of multiplying resources.

Commands and configuration

cd learn-vault/labs/bootstrap
./setup.sh
source ../../.runtime/learner.env
vault token lookup -format=json | jq '{policies:.data.policies,ttl:.data.ttl}'
vault token capabilities lockbox-kv/data/orders-api

Platform-team supplied context: approved OIDC environment

export VAULT_ADDR=https://vault.example.internal:8200
export VAULT_CACERT=/approved/path/vault-ca.crt
vault login -method=oidc -path=oidc -no-print role=developer
vault token lookup -format=json | jq '{policies:.data.policies,ttl:.data.ttl}'

-no-print stores the token through the configured token helper without displaying it. Do not use -no-store here because that option must print the token to make it usable.

Secret-safety stop

Stop: This lab uses local HTTP and Vault dev mode only on 127.0.0.1 with disposable data. Neither choice belongs in production.

Failure drill

Symptomvault status cannot connect.
Likely causesDocker stopped, port 8200 occupied, or VAULT_ADDR points elsewhere.
Inspect safelyRun docker compose ps, inspect port ownership, and print only VAULT_ADDR.
Do not printbootstrap.env, learner.env, token files, or container environment.

Break it / fix it

Break it: Point VAULT_ADDR at an unused local port.

Show diagnosis and fix

Fix it: Restore the loopback lab address, confirm Compose health, then repeat metadata-only login checks.

Escalate with time, endpoint, auth path, role, mount, namespace when relevant, status code, request ID, and sanitized error class. Never attach a credential or response body.

Try it

Bootstrap boundary

labs/bootstrap owns the disposable server, auth mounts, policies, roles, and engines; learner actions begin after setup.

Cost:

$0; local containers only

Starting state:

Run labs/bootstrap/setup.sh and source .runtime/learner.env unless the chapter lab says AppRole alone is sufficient.

User actions:

Run setup twice to prove idempotence, then use the separate human-user lab to inspect identity and prove an expected authorization denial.

cd learn-vault/labs/bootstrap
./setup.sh
./setup.sh
cd ../human-user
./inspect-identity.sh
./expected-denial.sh

Success criteria:

Complete every item in the Verify section using metadata-only evidence; no secret value appears in terminal output or tracked files.

Troubleshooting:

Use the Failure drill and Break it / fix it evidence fields. Stop before broadening policy, weakening identity or TLS checks, or copying secret-bearing diagnostics.

Verify

  1. The second setup run succeeds without duplicate-mount errors.
  2. Token lookup contains lockbox-learner and a finite TTL.
  3. The privileged action is denied.
Evidence rule: retain only status, policy names, TTLs, versions, timestamps, fingerprints, and error classes. Never retain secret values.

Cleanup

Run ./cleanup.sh when finishing a session. Re-running setup reconstructs all disposable state.

Project Lockbox increment

Tracked examples are separated from generated credentials and renders under ignored learn-vault/.runtime.

Quick check

Why not export the root token manually?

History, process inspection, copy-paste, and screenshots make it easy to leak.

Why run setup twice?

It verifies repeatable recovery for another learning session.

Why is local HTTP bounded here?

It is loopback-only and carries disposable lab data.

What is the clean reset?

Run cleanup, then setup again.

Gotchas

Recap and next

A safe tutorial treats its bootstrap credentials as secrets and makes reset cheaper than manual repair.

Primary references

Continue →