feat(gateway): phase7 public access layer (entitlements, rate limits, public list)
This commit is contained in:
106
docs/ops/phase7_public_access.md
Normal file
106
docs/ops/phase7_public_access.md
Normal file
@@ -0,0 +1,106 @@
|
||||
# Phase-7 Public Access Layer
|
||||
|
||||
## Scope
|
||||
- Public discovery endpoint: `GET /v1/agents/public`
|
||||
- Entitlements check in gateway before router call
|
||||
- Rate limits in gateway for:
|
||||
- `user_global`
|
||||
- `user_agent`
|
||||
- `group_agent`
|
||||
|
||||
## Data Model
|
||||
Migration: `migrations/056_agent_access_policies.sql`
|
||||
|
||||
Tables:
|
||||
- `agent_access_policies`
|
||||
- `agent_allowlist`
|
||||
|
||||
## Gateway Env
|
||||
- `GATEWAY_PUBLIC_ACCESS_ENABLED=true`
|
||||
- `GATEWAY_ACCESS_POLICY_CACHE_TTL_SECONDS=60`
|
||||
- `GATEWAY_ALLOWLIST_CACHE_TTL_SECONDS=30`
|
||||
- `GATEWAY_ACCESS_DB_TIMEOUT_MS=40`
|
||||
- `GATEWAY_ACCESS_DENY_COOLDOWN_SECONDS=30`
|
||||
- `GATEWAY_RL_USER_GLOBAL_LIMIT=60`
|
||||
- `GATEWAY_RL_USER_GLOBAL_WINDOW_SECONDS=300`
|
||||
- `GATEWAY_RL_USER_AGENT_LIMIT=20`
|
||||
- `GATEWAY_RL_USER_AGENT_WINDOW_SECONDS=300`
|
||||
- `GATEWAY_RL_GROUP_AGENT_LIMIT=10`
|
||||
- `GATEWAY_RL_GROUP_AGENT_WINDOW_SECONDS=300`
|
||||
|
||||
## Public Discovery
|
||||
```bash
|
||||
curl -sS http://127.0.0.1:9300/v1/agents/public | jq
|
||||
```
|
||||
|
||||
Expected:
|
||||
- `count` includes only `enabled && public_active` agents.
|
||||
- planned/internal agents are excluded.
|
||||
|
||||
## Entitlements Operations
|
||||
Add whitelist user:
|
||||
```sql
|
||||
INSERT INTO agent_allowlist(platform, platform_user_id, agent_id)
|
||||
VALUES ('telegram', '123456789', 'helion')
|
||||
ON CONFLICT (platform, platform_user_id, agent_id) DO NOTHING;
|
||||
```
|
||||
|
||||
Require whitelist for an agent:
|
||||
```sql
|
||||
UPDATE agent_access_policies
|
||||
SET requires_whitelist = TRUE, updated_at = now()
|
||||
WHERE agent_id = 'helion';
|
||||
```
|
||||
|
||||
Disable agent public access:
|
||||
```sql
|
||||
UPDATE agent_access_policies
|
||||
SET enabled = FALSE, public_active = FALSE, updated_at = now()
|
||||
WHERE agent_id = 'aistalk';
|
||||
```
|
||||
|
||||
## Rate-Limit Policy Update
|
||||
```sql
|
||||
UPDATE agent_access_policies
|
||||
SET
|
||||
user_global_limit = 30,
|
||||
user_global_window_seconds = 300,
|
||||
user_agent_limit = 10,
|
||||
user_agent_window_seconds = 300,
|
||||
group_agent_limit = 5,
|
||||
group_agent_window_seconds = 300,
|
||||
updated_at = now()
|
||||
WHERE agent_id = 'agromatrix';
|
||||
```
|
||||
|
||||
## Fixed Smoke
|
||||
1. Discovery:
|
||||
```bash
|
||||
curl -sS http://127.0.0.1:9300/v1/agents/public | jq '.count'
|
||||
```
|
||||
|
||||
2. Whitelist deny:
|
||||
- Set `requires_whitelist=true` for test agent.
|
||||
- Replay webhook from user not in allowlist.
|
||||
- Expected: deny ACK and event reason `access_whitelist_required`.
|
||||
|
||||
3. Whitelist allow:
|
||||
- Insert user to `agent_allowlist`.
|
||||
- Replay webhook.
|
||||
- Expected: request continues to normal processing path.
|
||||
|
||||
4. Rate limit:
|
||||
- Set low policy (`user_agent_limit=2`, window 60s).
|
||||
- Send 3 quick webhooks from same user/agent.
|
||||
- Expected: third request is `429`-style deny path and `reason=rate_limit_user_agent`.
|
||||
|
||||
5. Event invariant:
|
||||
- `1 webhook -> 1 gateway event` remains true.
|
||||
|
||||
## PASS
|
||||
- `/v1/agents/public` returns only public enabled agents.
|
||||
- Entitlement decisions are deterministic (`allow|deny|rate_limited`).
|
||||
- Metrics increment:
|
||||
- `gateway_access_decisions_total`
|
||||
- `gateway_rate_limited_total`
|
||||
- No regression in webhook event finalize behavior.
|
||||
Reference in New Issue
Block a user