auth-and-rbac
FastAPI auth patterns — session/JWT chains, argon2id hashing, pyotp TOTP/Email OTP, role-based access control, x-user-data gateway forwarding.
Skill by ajyadav013
Install
Works with Claude Code, Claude apps, Codex, Cursor, Gemini CLI, GitHub Copilot, VS Code, OpenCode, Goose, Windsurf. Read the repository before you give any tool access to your data.
npx agentmarket install skill/ajyadav013-auth-and-rbac
Asks which of your tools to add it to (Claude Code, Codex, Cursor, VS Code, Windsurf, Gemini CLI, Claude Desktop) and shows the change first. See https://agentmart.dev/cli.
Get the weekly diff
The weekly diff: one email a week with new agent tools, notable updates and grade changes, plus security alerts for tools you follow. Double opt-in, one-click unsubscribe.
About
Use cases: backend, data, security, productivity
Reviews
Write a reviewNo reviews yet. Installed it? Reviews come from verified installers only. How reviews work
Permissions
What this skill can do and what it asks for, from its SKILL.md and code. Checked Oct 26, 2026.
- Tools
- No tools found
- Secrets
- None asked for
- Install scripts
- None found
Network hosts it talks to 1
codeload.github.com· found in install command
Files it touches
~/.claude/skills/auth-and-rbac
What's inside
- Skill name
auth-and-rbac- Description
- FastAPI auth patterns — session/JWT chains, argon2id hashing, pyotp TOTP/Email OTP, role-based access control, x-user-data gateway forwarding. Use when building auth dependencies, MFA, or role hierarchies.
- License
- MIT
- Instructions
- 343 lines in SKILL.md · view on GitHub
Files (8)
- SKILL.md
- auth-dependencies.md · references/
- htn-design-an-authentication-system.md · references/
- htn-serialization-deserialization-authentication-and-authorizati.md · references/
- rbac-and-permissions.md · references/
- repo-evidence.md · references/
- security-hardening.md · references/
- tokens-and-hashing.md · references/
SKILL.md (first lines)
# Auth and RBAC
FastAPI authentication and authorization patterns derived from production identity services and multi-tenant backends.
## When to use
- Implementing session-based or JWT authentication in FastAPI
- Building role-based access control (RBAC) with hierarchical roles (sys_admin > org_admin > sub_org_admin > tenant_admin > member)
- Implementing multi-factor authentication (TOTP or Email OTP) with pyotp
- Designing auth dependency chains with `Depends(require_auth)` and role-specific guards
- Integrating with API gateways that forward identity via custom headers (x-user-data JSON)
- Hashing passwords with argon2id in async thread pool to avoid blocking the event loop
- Enforcing org/tenant access checks with materialized path hierarchies
- Issuing RS256 JWT tokens with key rotation and JWKS endpoint
- Implementing refresh token rotation for secure long-lived sessions
- Adding rate limiting to login endpoints to prevent brute-force attacks
- Enforcing password expiry policies and rotation tracking
- Implementing session fingerprinting to detect hijacking attempts
## Core conventions
### Authentication Dependency Chain
**Session-based auth chain**: `get_current_session` extracts session ID from cookie → validates in Redis → decrypts → `require_auth` verifies fingerprint + request signature → role dependencies (`require_sys_admin`, `require_org_admin_or_above`, `require_sub_org_admin_or_above`) enforce RBAC.
**JWT auth chain**: `get_current_user_jwt` extracts `Authorization: Bearer` header → decodes with PyJWT → verifies signature with RS256 public key → loads user from DB → returns session-shaped dict `{"user": {...}}` compatible with downstream dependencies.
**Helper extractors**: `get_caller_user_id(session)`, `get_caller_org_id(session)`, `get_caller_role(session)`, `is_sys_admin(session)` for inline role checks in endpoint logic.
**Fingerprint validation**: Store `_fingerprint` (IP + User-Agent hash) in session; on each request, recompute and compare — mismatch deletes session and returns 401.
**Request signing (optional)**: Store client ECDSA public key `_public_key` in session; require `x-request-signature` + `x-request-timestamp` headers; verify ECDSA signature over `method|path|body|timestamp`.
### Password Hashing (argon2id)
**Async hashing**: Use `argon2.PasswordHasher` with `time_cost=3, memory_cost=65536, parallelism=4, hash_len=32, salt_len=16`; wrap `ph.hash(password)` and `ph.verify(hash, password)` in `asyncio.to_thread()` to avoid blocking the event loop.
**Password rotation tracking**: Store hashed password history in `password_history` table; `check_password_reuse` queries the last N passwords and verifies new password doesn't match any via `verify_password`.
**Rehash check**: Call `ph.check_needs_rehash(hash)` on login; if params have changed, rehash and update DB.
### JWT Tokens (RS256)
**Token issuance**: Generate RS256 JWT with `pyjwt.encode(payload, private_key, algorithm='RS256', headers={'kid': key_id})`; include `sub` (user_id), `email`, `role`, `organization_id`, `exp`, `iat`, `iss`, `aud` in payload.
**Refresh tokens**: Issue opaque UUID refresh tokens; store `{user_id, issued_at}` in Redis `refresh_token:{uuid}` with expiry; on refresh, delete old token (rotation), validate user is still active, issue new pair.
**JWKS endpoint**: Expose `/.well-known/jwks.json` with active public keys as JWK Set; include `kid`, `kty`, `use`, `alg`, `n`, `e` for each key.
**Key rotation**: Store private keys encrypted at rest (Fernet); mark old keys as inactive; new tokens use latest active key; verification accepts any active key by `kid`.
**Token verification flow**: Extract `kid` from unverified header → fetch signing key from DB → decode with `pyjwt.decode(token, public_key, algorithms=['RS256'], audience=..., issuer=...)` → validate claims → check revocation (optional).
### MFA with pyotp
**TOTP setup**: Generate secret with `pyotp.random_base32(length=32)` → create QR URI with `pyotp.totp.TOTP(secret).provisioning_uri(name=user.email, issuer_name="AppName")` → return to client once.
**TOTP verification**: Verify code with `pyotp.TOTP(secret).verify(code, valid_window=1)` (accepts ±30s drift).
**Email OTP**: Generate 6-digit code, store in Redis `email_otp:{user_id}` with TTL=300s and attempt counter; verify code + attempt count; implement resend cooldown (60s).
**Backup codes**: Generate 10 random 8-char alphanumeric codes; hash each with SHA-256; store hashes; on use, verify one-time then mark as used.
**MFA enforcement**: Check org-level MFA policy table; if user role or org requires MFA and user has no active enrollments, block login with 403 and message "MFA enrollment required".
**MFA pending session**: On login with MFA, create temp `mfa_pending:{session_token}` in Redis (TTL=300s) with `{user_id, mfa_methods: ['TOTP', 'EMAIL_OTP'], type: 'mfa_pending'}` → return `{mfa_required: true, session_token, methods}` → client submits code → verify → upgrade to full session.
### Role-Based Access Control
**Role hierarchy**: `sys_admin` (platform superuser) > `org_admin` (org tree root admin) > `sub_org_admin` (subtree admin) > `tenant_admin` (single org/tenant) > `member` (read-only or limited scope).
**Role dependency pattern**: Create FastAPI dependencies that accept `session: dict = Depends(require_auth)` and check `session.get("user", {}).get("role")` — raise 403 if insufficient role.
**Hierarchical org access checks**: `assert_org_access_async(session, target_org_id, connection_handler)` — `sys_admin` always passes; `org_admin` checks root path prefix match; `sub_org_admin` checks subtree prefix match; `tenant_admin`/`member` require exact org_id match.
**Org path pattern**: Store org hierarchy as materialized path `/root/parent/child/`; admins can manage orgs in their subtree by path prefix comparison.
**Role enum**: Define `class Role(str, Enum): L1 = "L1"; L2 = "L2"; ADMIN = "ADMIN"` for domain-specific roles; store as string column with enum constraint.
### Choosing an authorization model & OAuth 2.0 delegation
Everything above assumes RBAC. That is usually right, but treat the authorization model as a decision, not a default — and know when to delegate identity to an external provider instead of owning credentials at all.
**The three models**:
- **RBAC (roles → permissions)** — users hold roles; roles bundle permission sets (admin = full CRUD, editor = read+write, member = read-only). Easiest to audit and administer; the right default for org/team products where a small, stable set of permission tiers answers most access questions.
- **ABAC (attribute predicates)** — decisions are policy functions over attributes of the subject, resource, and context: "the author may edit their own draft", "department matches", "within business hours", "resource not archived". Reach for it when access depends on ownership, tenancy, time, or resource state — conditions a static role cannot express. More expressive, harder to audit.
- **ACL (per-object grant lists)** — each resource carries its own principal→rights list, the document-sharing / filesystem model. The natural fit for sharing-centric products (docs, files, folders); maximally precise, but management cost scales with resources × users, so it needs tooling.
**Decision heuristics**:
- Permission tiers are few, stable, and org-wide → RBAC (this skill's role dependencies and hierarchy checks are exactly this).
- Rules keep referencing who owns the resource, which tenant it belongs to, what state it is in, or when the request happens → ABAC predicates alongside your roles.
- Users grant each other access object-by-object → ACL rows on those resources.
**The hybrid most systems actually run**: RBAC for coarse tiers plus ABAC-style ownership checks in business logic (`if resource.owner_id != caller_user_id and not is_sys_admin(session): 403`). Name it explicitly — "RBAC + ownership" — so reviewers treat both layers as intentional, and enforce it at every depth (route guard, service-level ownership check, query scoping to the caller's rows); relying on the route guard alone is the classic IDOR root cause.
**Migration pressure signals**:
- **Role explosion** — compound roles multiplying (`editor_finance_emea_readonly`) means your rules are really attribute predicates; move those conditions into ABAC checks instead of minting more roles.
- **Per-resource sharing requests** — users wanting to grant specific people access to specific objects cannot be expressed as a role tier; those objects need ACL entries.
**OAuth 2.0 authorization-code flow** — for social login ("Login with Google/GitHub") or calling a third-party API on the user's behalf:
1. Your app redirects the browser to the provider's authorization server (`client_id`, `redirect_uri`, requested scopes, `state`).
2. The user authenticates and consents at the provider — your system never sees their password.
3. The provider redirects back to your `redirect_uri` with a short-lived, single-use authorization code.
4. Your backend exchanges code + client secret for tokens in a server-to-server call.
5. Your backend verifies the returned identity, then links or creates the local user row.
**Why the code indirection**: browser redirects are observable (URLs land in history, proxies, logs, referrers), so nothing in a redirect may be a usable credential. An intercepted code is worthless without the client secret held server-side. Never use the legacy implicit flow, which returns the access token directly in the URL fragment.
**PKCE for public clients**: SPAs and mobile apps cannot hold a client secret; use authorization-code + PKCE, where a per-request code verifier/challenge pair replaces the secret in the exchange.
**Callback CSRF protection**: generate a random `state` value per authorization request, bind it to the initiating session, and reject any callback whose `state` does not match — otherwise an attacker can splice their own authorization code into a victim's login.
**What to persist**: the provider's stable subject identifier linked to your own user row (`provider` + `provider_subject_id` columns); match returning users on that pair, not on email, which can change or be reassigned at the provider.
**The provider's access token is not your session**: it is scoped to the provider's API, has a lifetime you do not control, and your services cannot validate it. After linking identity, issue your own session or JWT via the chains above; store the provider token (encrypted at rest) only if you actually call the provider's API on the user's behalf.From ajyadav013/claude-kit, MIT.
More from ajyadav013/claude-kit
- 0.602score
design-patterns-and-conventions
ajyadav013
Cross-cutting design patterns, naming, folder layout, and anti-patterns for production Python/FastAPI backends.
SkillBFreshness: B★ 14Claude Code +9 - 0.602score
async-python-patterns
ajyadav013
Async Python for high-performance services.
SkillBFreshness: B★ 14Claude Code +9 - 0.602score
data-engineering-bigquery-gcs
ajyadav013
BigQuery medallion architecture (bronze/silver/gold), parameterized queries, MERGE upserts, partitioning, CDC dedup, Temporal orchestration.
SkillBFreshness: B★ 14Claude Code +9 - 0.602score
cron-and-scheduled-jobs
ajyadav013
Scheduled jobs across two mechanisms — Kubernetes CronJobs (schedule in Helm values, MODE=cron) and Temporal Schedules.
SkillBFreshness: B★ 14Claude Code +9 - 0.602score
api-and-interface-design
ajyadav013
Stable API and interface design patterns.
SkillBFreshness: B★ 14Claude Code +9 - 0.602score
api-pagination-filtering-sorting
ajyadav013
HTTP query parameter conventions for pagination, filtering, sorting, and search with standardized response metadata.
SkillBFreshness: B★ 14Claude Code +9 - 0.602score
code-simplification
ajyadav013
Simplifies/refactors working code for clarity without changing behavior.
SkillBFreshness: B★ 14Claude Code +9 - 0.602score
backend-repo-architecture
ajyadav013
Canonical backend repository structure for Python/FastAPI — multi-mode entrypoint, app factory, ConnectionManager, BaseDao, flat vs versioned layout.
SkillBFreshness: B★ 14Claude Code +9 - 0.602score
docker-shared
ajyadav013
Shared Docker building blocks — base images for private registries, .dockerignore conventions, compose fragment reuse with YAML anchors.
SkillBFreshness: B★ 14Claude Code +9 - 0.602score
dockerfile-backend
ajyadav013
Multi-stage Dockerfiles for Python/FastAPI backends — builder vs runtime, slim vs alpine, system deps, layer caching, non-root users.
SkillBFreshness: B★ 14Claude Code +9 - 0.602score
anthropic-vertex-integration
ajyadav013
Claude on Vertex AI via the AnthropicVertex SDK — lazy ADC client init, env-based project/region resolution, async helpers, backoff retry.
SkillBFreshness: B★ 14Claude Code +9 - 0.602score
distributed-systems-patterns
ajyadav013
Distributed data placement and replication — consistent hashing/vnodes, sharding, N/W/R quorums, KV-store and cache anatomy, gossip failure detection, B-tree…
SkillBFreshness: B★ 14Claude Code +9
Signals
- Stars
- 14
- Forks
- 5
- Open issues
- 9
- Last commit (this folder)
- Aug 22, 2026 (2 months ago)
- Last release
- Sep 7, 2026 (1 month ago)
From GitHub (fetched Oct 24, 2026).
Details
- License
- MIT
- Repository
- github.com/ajyadav013/claude-kit
- First seen
- Oct 24, 2026
- Last checked
- Oct 24, 2026
- Source
- GitHubgithub-graphql
More from ajyadav013
- 0.602score
anthropic-vertex-integration
ajyadav013
Claude on Vertex AI via the AnthropicVertex SDK — lazy ADC client init, env-based project/region resolution, async helpers, backoff retry.
SkillBFreshness: B★ 14Claude Code +9 - 0.602score
dockerfile-backend
ajyadav013
Multi-stage Dockerfiles for Python/FastAPI backends — builder vs runtime, slim vs alpine, system deps, layer caching, non-root users.
SkillBFreshness: B★ 14Claude Code +9 - 0.602score
code-simplification
ajyadav013
Simplifies/refactors working code for clarity without changing behavior.
SkillBFreshness: B★ 14Claude Code +9 - 0.602score
cron-and-scheduled-jobs
ajyadav013
Scheduled jobs across two mechanisms — Kubernetes CronJobs (schedule in Helm values, MODE=cron) and Temporal Schedules.
SkillBFreshness: B★ 14Claude Code +9 - 0.602score
docker-shared
ajyadav013
Shared Docker building blocks — base images for private registries, .dockerignore conventions, compose fragment reuse with YAML anchors.
SkillBFreshness: B★ 14Claude Code +9 - 0.602score
api-and-interface-design
ajyadav013
Stable API and interface design patterns.
SkillBFreshness: B★ 14Claude Code +9
Cite this page
auth-and-rbac skill. Agent Mart. https://agentmart.dev/skills/ajyadav013-auth-and-rbac (last updated 2026-10-24)