docs: draft task file for Ingress Grant Injection in forward-auth
Creates a new task markdown file in `tasks/new` detailing the architecture and implementation steps required to inject flattened RBAC grants via Valkey caching for `/api/forward-auth`. Co-authored-by: mrteye <1945243+mrteye@users.noreply.github.com>
This commit is contained in:
parent
cf64161a8b
commit
38310f4ead
@ -0,0 +1,82 @@
|
|||||||
|
# TASK METADATA
|
||||||
|
|
||||||
|
- **Target Files:** `server/main.ts`, `server/db.ts`, `server/auth-session.ts`
|
||||||
|
- **Core Objective:** Implement Ingress Grant Vector Injection in
|
||||||
|
`/api/forward-auth` to resolve `X-Forwarded-Host` against registered apps,
|
||||||
|
evaluate RBAC grants via Valkey caching, and inject flattened user grant
|
||||||
|
headers into downstream requests.
|
||||||
|
- **Dependencies:** Valkey caching infrastructure, database migration for
|
||||||
|
`domain` column on `apps` table.
|
||||||
|
- **Additional Important Notes:** Latency is critical; ForwardAuth must resolve
|
||||||
|
in <30μs using Valkey and must not hit PostgreSQL on every request. Global
|
||||||
|
Admins bypass app-specific grant checks.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Architectural Considerations & Risks
|
||||||
|
|
||||||
|
### Risks
|
||||||
|
|
||||||
|
- **Cache Invalidation:** Stale data in Valkey could allow revoked users to
|
||||||
|
retain access or prevent newly granted users from accessing apps. We must
|
||||||
|
ensure that grants and app updates properly invalidate or update their
|
||||||
|
respective Valkey keys.
|
||||||
|
- **Header Spoofing / Parsing Issues:** Ensure the `X-Forwarded-*` headers are
|
||||||
|
safely injected and override any existing headers from the client to prevent
|
||||||
|
privilege escalation (handled by Traefik, but good to be mindful of).
|
||||||
|
- **Performance Bottlenecks:** While caching resolves database latency, improper
|
||||||
|
cache interactions (e.g., waiting for multiple sequential round-trips to
|
||||||
|
Valkey instead of using pipelining or MGET where appropriate) could still add
|
||||||
|
overhead.
|
||||||
|
|
||||||
|
### Alternatives Evaluated
|
||||||
|
|
||||||
|
- **Direct PostgreSQL queries:** Rejected due to the high volume of requests
|
||||||
|
hitting the edge proxy `/api/forward-auth`.
|
||||||
|
- **JWT Injection:** Instead of flattened headers, injecting a signed JWT was
|
||||||
|
considered. However, flattened headers (`X-Forwarded-User-Id`,
|
||||||
|
`X-Forwarded-Scopes`) are native to Traefik ForwardAuth and simpler for
|
||||||
|
downstream SSR hydration without requiring public key distribution to every
|
||||||
|
downstream app.
|
||||||
|
|
||||||
|
## Proposed Implementation
|
||||||
|
|
||||||
|
### 1. Database Schema Update (`server/db.ts`)
|
||||||
|
|
||||||
|
- Modify `initDb()` to add the `domain` column to the `apps` table:
|
||||||
|
`ALTER TABLE apps ADD COLUMN IF NOT EXISTS domain TEXT;`.
|
||||||
|
- Ensure application seeding or registry logic accounts for the new `domain`
|
||||||
|
field if necessary.
|
||||||
|
|
||||||
|
### 2. Caching Strategy Implementation
|
||||||
|
|
||||||
|
- Implement helper functions to fetch from Valkey or fallback to DB and populate
|
||||||
|
Valkey.
|
||||||
|
- **App Resolution Cache (`auth:app_by_host:<host>`):**
|
||||||
|
- Match `X-Forwarded-Host` against `apps.domain`.
|
||||||
|
- Fallback: Match `apps.name` against the first subdomain segment.
|
||||||
|
- Cache the resulting `app_id` and `name` in Valkey as JSON.
|
||||||
|
- **Grants Cache (`auth:grants:<userId>:<appId>`):**
|
||||||
|
- Cache the user's roles for the specific app.
|
||||||
|
|
||||||
|
### 3. ForwardAuth Endpoint Logic (`server/main.ts`)
|
||||||
|
|
||||||
|
- Update `GET /api/forward-auth` to:
|
||||||
|
1. Extract `X-Forwarded-Host` from the request.
|
||||||
|
2. Resolve the target application via the App Resolution Cache (Valkey). If no
|
||||||
|
app matches, decide whether to allow pass-through without scopes or
|
||||||
|
strictly deny (typically 403 for protected routes without an app, or allow
|
||||||
|
pass-through if unmapped). Assuming strict mapping per requirements, return
|
||||||
|
403 or 404 if not found.
|
||||||
|
3. Validate the user session (existing logic).
|
||||||
|
4. Check if the user is a Global Admin (`isGlobalAdmin`). If yes, authorize
|
||||||
|
automatically and set `X-Forwarded-Scopes: admin`.
|
||||||
|
5. For regular users, resolve their scopes for the target app via the Grants
|
||||||
|
Cache (Valkey).
|
||||||
|
6. Enforce Default-Deny: If no scopes are found, return 403 Forbidden.
|
||||||
|
7. On success, inject headers:
|
||||||
|
- `X-Forwarded-User-Id: <user.id>`
|
||||||
|
- `X-Forwarded-User-Name: <user.username>`
|
||||||
|
- `X-Forwarded-Scopes: <comma-separated list of roles>`
|
||||||
|
- `X-Forwarded-App-Id: <app_id>`
|
||||||
|
- Return HTTP 200 OK.
|
||||||
Loading…
x
Reference in New Issue
Block a user