id is the TACACS username
lab-admin → group administrators (priv-lvl 15). lab-readonly → readonly (priv-lvl 1). lab-disabled is off. UsernameCasePreserved — not lowercased.
schema_version: 1 · file-referenced secrets · memory overlay
There is no persisted AAA database. Users, groups, clients, tokens, and listeners live in
config/taclab.yaml. Passwords and shared secrets live in files under secrets/.
Canonical write-up: docs/BASELINE.md.
| Path | Holds |
|---|---|
config/taclab.yaml | Users, groups, clients, bootstrap tokens, listeners, policy |
secrets/api_admin_token | REST / MCP / UI bearer |
secrets/lab_admin_argon2id | ASCII/PAP verifier for lab-admin |
secrets/lab_admin_enable_argon2id | ENABLE verifier |
secrets/lab_admin_challenge_secret | CHAP / MS-CHAP (not hashed) |
secrets/lab_readonly_argon2id | ASCII/PAP for lab-readonly |
secrets/lab_switches_tacacs_secret | Legacy device shared secret |
secrets/PASSWORDS.txt | Human crib only — daemon never reads it |
Unknown YAML fields fail closed. taclabd never rewrites the baseline. Runtime overlay is memory-only.
lab-admin → group administrators (priv-lvl 15). lab-readonly → readonly (priv-lvl 1). lab-disabled is off. UsernameCasePreserved — not lowercased.
services[] never decide a cmd. command_rules[] never decide a session. YAML permit is an alias of permit_add.
lab-switches on :49 with a per-client secret. secure-routers on :300 with mTLS. Match uses the TCP peer TacLab sees.
Argon2id login verifier for ASCII/PAP. Separate challenge secret for CHAP/MS-CHAP. Separate ENABLE verifier. Never mix them.
users:
- id: netops
display_name: Network operations
enabled: true
group_ids: [readonly]
credentials:
login:
verifier:
file: /run/secrets/netops_argon2id
restrictions:
client_ids: []
Then add netops_argon2id to compose.yaml (service list and top-level secrets:), put the PHC file in secrets/, taclabd validate, and docker compose up -d. Reload alone cannot mount a new Docker secret.
YAML + secret files survive restart. That is the lab you can check in (minus secrets) and rebuild.
taclab.users.create accepts a password once and stores Argon2id. Gone on restart or runtime.reset.