Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
fcc8616
feat(audit): phase 1 — per-user attribution, security-event stream, a…
CMGS Jul 15, 2026
7e503cf
review: apply phase-1 simplify findings (dedup user-id resolution, ad…
CMGS Jul 15, 2026
dbfb25c
feat(security): phase 2 (B1-B3) — per-tenant policy, action tiers, re…
CMGS Jul 15, 2026
ae72f1a
feat(retention): phase 2 (C2/C4/D2) — gated content retention, purge,…
CMGS Jul 15, 2026
a096fc1
feat(phase3): moderation seam + per-user budgets
CMGS Jul 15, 2026
e80b653
review: apply phase-2 simplify findings (zero-alloc part redaction, l…
CMGS Jul 15, 2026
92b758f
docs: document per-tenant audit/security/retention knobs in the embed…
CMGS Jul 15, 2026
9a895f5
docs: per-user billing, enterprise content policy, and audit trails i…
CMGS Jul 15, 2026
045d149
fix(review): rev-safety + rev-isolation findings
CMGS Jul 15, 2026
5e52413
fix(realtime): resolve x-gw-user for billing, budget, and security ev…
CMGS Jul 15, 2026
2b8fee3
refactor(attribution): single AkInfo::attributed_user across REST and…
CMGS Jul 15, 2026
94199a9
fix(security): close realtime secret-redaction, keyless-full retentio…
CMGS Jul 15, 2026
64e7388
fix(batch): persist per-item user attribution so shared-key batches b…
CMGS Jul 15, 2026
06667a9
fix(audit): root admin source IP at the TCP peer, trust proxy headers…
CMGS Jul 15, 2026
29eac92
docs: per-surface user attribution, retention redaction guarantee, au…
CMGS Jul 15, 2026
db7e819
fix(realtime): apply external moderation; freeze audit source IP pre-…
CMGS Jul 15, 2026
b712d5c
fix(realtime): audit outbound DLP per turn; reconcile the doc exemption
CMGS Jul 15, 2026
55e041e
fix(realtime): flush aborted-turn outbound DLP audit on exit
CMGS Jul 15, 2026
3416667
review: apply simplify+code-rs convergence round (policy seams, hot-p…
CMGS Jul 15, 2026
0c9ceae
feat(retention): read retained content back via /admin/audit/content/…
CMGS Jul 15, 2026
c810598
docs: document per-user attribution, audit trails, content policy, an…
CMGS Jul 15, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
100 changes: 99 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -76,10 +76,12 @@ gw-task = { path = "crates/task" }
gw-views = { path = "crates/views" }
base64 = "0.22"
tiktoken-rs = "0.12"
# pure-compute crypto (SigV4 signing, cache keys) — no network capability
# pure-compute crypto (SigV4 signing, cache keys, content-at-rest AEAD) — no network capability
sha2 = "0.10"
hmac = "0.12"
hex = "0.4"
chacha20poly1305 = "0.10"
regex = "1"

# Faster iterative builds; keep release optimized.
[profile.dev]
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ key-based auth, quotas, rate limits, failover, and a billing ledger.
- **Staged request pipeline** — a 4-layer DAG per request: model resolve / quota / cache lookup → account selection (priority, PTU-first, failover) → rate limits + engine call (retry on upstream 5xx) → usage extraction, billing, cache store
- **Governance built in** — access-key auth, daily token quotas, QPS / QPM / TPM limits at key, product, and model level, request-level TTL cache, account cooldown and recovery, DLP redaction and blocklist plugins. Admission reserves then settles, so concurrent requests can't overshoot a quota
- **Multi-tenant** — keys carry a tenant; tenants get a pooled QPS bucket, a model entitlement allowlist, per-(key, model) quota defaults with an optional fallback-model degrade, key lifecycle (expiry/ban), and tenant-scoped admin tokens. Billing records charged cost and (optionally) vendor cost per row, so margin is queryable per tenant × model
- **Per-user billing & enterprise audit** — every ledger row attributes to an effective end user (the key's `owner`, else the request's `x-gw-user` / `user` hint) with a `request_id`, so cost rolls up per user (`/admin/usage/users`) and a soft per-user daily budget applies on every surface. Per-tenant content policy adds blocklist action tiers (block / flag / shadow), regex recognizers, secret masking, and an external-moderation seam; every hit is recorded without prompt text. An admin-operation trail (key CRUD / config / reload, with source IP) and optional at-rest content retention complete the audit surfaces (`/admin/audit/*`)
- **Fleet-ready** — run N instances behind a load balancer: Postgres shares config (versioned + a change feed), the access-key table, the ledger/files/batches store, and a distributed batch queue any instance drains; Redis shares rate/quota/TPM counters, account health, and optionally the response cache. Single-node stays zero-dependency
- **Providers behind traits** — engines talk to upstreams through a `Transport` seam; accounts with a real endpoint go over HTTP (reqwest + rustls), accounts without one are served by a deterministic in-process mock; AWS SigV4 signing included
- **Observability built in** — Prometheus `/metrics` (per-route request/status counters, per-pipeline-stage latency, token counters), structured access logs
Expand Down
11 changes: 11 additions & 0 deletions conf/gateway.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,17 @@ tenants:
fallback_model: gpt-4o-mini
model_prices: # e2e: tenant pays a premium over the list price
gpt-4o: {input_price_per_1k_micros: 5000, output_price_per_1k_micros: 20000}
# Optional per-tenant knobs (enterprise audit/compliance):
# user_daily_token_quota: 100000 # soft per-end-user daily cap
# retention: {content: redacted, days: 30} # none | redacted | full (full needs GW_CONTENT_KEY)
# security: # overrides the global `security:` for this tenant
# blocklist: ["forbidden"]
# blocklist_action: flag # block | flag | shadow
# dlp_redact: true
# detect_secrets: true # mask API keys / credentials
# moderate: false # route to the wired external moderator
# regex_rules:
# - {name: ssn, pattern: '\d{3}-\d{2}-\d{4}', action: block}

# Public model name → wire protocol, optional provider binding (only that
# provider's accounts serve the model), plus demo prices (micros per 1k tokens).
Expand Down
2 changes: 2 additions & 0 deletions crates/config/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ gw-consts = { workspace = true }
serde = { workspace = true }
serde_yaml = { workspace = true }
thiserror = { workspace = true }
regex = { workspace = true }
tracing = { workspace = true }

[lints]
workspace = true
Loading
Loading