# 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.