# RBAC roles + user → role mapping. # # Single source of truth for both main backend (backend/app/core/auth.py) and # tradein backend (tradein-mvp/backend/app/core/auth.py). Mounted into both # containers at /app/auth/roles.yaml via docker-compose bind-mount. # # Glob semantics (fnmatch-based, see app.core.auth.is_path_allowed): # - "/**" → matches any path (admin scope). # - "/foo/**" → matches /foo, /foo/, /foo/bar, /foo/bar/baz/... # - "/foo" → matches exactly /foo. # # A path is allowed iff (1) it matches one of `paths` AND (2) it does NOT match # any pattern in `deny`. `deny` overrides `paths` (deny-by-default within # match scope). # # Username list MUST match exactly the 12 entries in caddy/users.caddy.snippet # — Caddy basic_auth sets X-Authenticated-User from {http.auth.user.id}, and # unknown users hit /me with 403 ("user not in roles config"). # # Last updated: 2026-05-26 (PR A — RBAC). roles: admin: paths: - "/**" deny: [] pilot: paths: - "/" - "/analytics/**" - "/site-finder/**" - "/trade-in/**" - "/concept/**" - "/api/v1/**" - "/trade-in/api/v1/**" deny: - "/admin/**" - "/api/v1/admin/**" - "/trade-in/api/v1/admin/**" users: admin: admin kopylov: pilot user1: pilot user2: pilot user3: pilot user4: pilot user5: pilot user6: pilot user7: pilot user8: pilot user9: pilot user10: pilot