bascule-oss/docs/authentication.md
Tyler King 043b9b9bdc feat: bascule-shell — identity-aware shell with TPM attestation
New crate: bascule-shell (471 lines, 1.8MB binary)
  Login shell that detects identity + platform attestation at startup.
  Wraps bash/zsh/fish — operator works normally, identity travels with them.

Identity detection (priority order):
  1. Entra via WSL2 interop
  2. Azure CLI
  3. Kerberos TGT
  4. Cached OIDC token
  5. System user (fallback)

Platform attestation:
  TPM 2.0 PCR values via tpm2_pcrread (PCRs 0,1,2,7,10,14)
  IMA measurement log hash + count
  Keylime agent state
  Entra device compliance (WSL2 only)
  Composite SHA-256 hash over all evidence

Shell features:
  Banner with identity + attestation summary
  BASCULE_* env vars injected into inner shell
  --info mode for dry-run display
  --json mode for machine-readable output
  --exec mode for single-command execution
  Configurable via ~/.config/bascule/shell.toml

Tested on Fedora with real TPM 2.0:
  6 PCRs successfully read from hardware
  All env vars propagated to inner shell
  1.8MB binary, 0 substrate deps

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-05 09:47:46 -04:00

2.2 KiB

Authentication

Bascule supports multiple authentication methods. Configure via [auth] in your TOML config.

accept-all (Development Only)

Accepts any SSH key or password. Never use in production.

[auth]
mode = "accept-all"

authorized-keys

Standard SSH authorized_keys file, same format as OpenSSH.

[auth]
mode = "authorized-keys"
authorized_keys_path = "/etc/bascule/authorized_keys"

The file format is identical to ~/.ssh/authorized_keys:

ssh-ed25519 AAAAC3NzaC1l... user@host
ssh-rsa AAAAB3NzaC1yc2... another-user@host

The authorized_keys_path can point to either:

  • A single file (all users share the same key list)
  • A directory with per-user key files: {dir}/{username}/authorized_keys

Entra Agent ID (AI Agents)

Microsoft Entra Agent ID authentication for AI agents. Requires the agent-id feature flag.

Agents present their OAuth token as the SSH password.

[auth]
mode = "authorized-keys"

[auth.agent_id]
tenant_id = "your-entra-tenant-id"
audiences = ["api://bascule-proxy"]
multi_tenant = false

When both authorized-keys and [auth.agent_id] are configured, Bascule composes them: SSH key auth for humans, token-as-password auth for agents.

How agents authenticate

  1. Agent obtains an OAuth token from Entra via client_credentials flow
  2. Agent connects via SSH: ssh agent-name@proxy -p 2222
  3. Agent provides the OAuth token as the SSH password
  4. Bascule validates the token against Entra's JWKS
  5. Session created with auth_method: "agent-id" and full agent metadata

Agent metadata extracted

From the validated token, Bascule extracts:

  • Agent application ID
  • Display name
  • Agent type (from custom claims)
  • Blueprint ID (Entra Agent ID template)
  • Sponsor (human/org that registered the agent)
  • On-behalf-of (if agent is delegated)
  • Scopes and roles

Your SessionHandler receives this in SessionInfo and can apply different policies for human vs agent sessions.

Composing Auth Providers

Bascule tries auth methods in order:

  1. SSH public key (if configured)
  2. Password / token-as-password (if configured)

Humans use SSH keys. Agents use token-as-password. Both work through the same SSH server.