Skip to content

feat(auth): gateway completeness, TenantId extractor, POST /auth/validate, Procfile#1129

Open
geoffjay wants to merge 2 commits intofeature/corefrom
issue-1116
Open

feat(auth): gateway completeness, TenantId extractor, POST /auth/validate, Procfile#1129
geoffjay wants to merge 2 commits intofeature/corefrom
issue-1116

Conversation

@geoffjay
Copy link
Copy Markdown
Owner

Implements all four checklist items from the auth integration foundation issue:

  • Gateway completeness: adds memory (17008), communicate (17010), and index (17012) to ProxyConfig::from_env() with env-override support and expanded tests
  • TenantId extractors: new agentd-common::tenant module with TenantId (permissive/strict via AGENTD_REQUIRE_TENANT) and OptionalTenantId (always succeeds, returns Option<String>) — 5 tests covering all modes
  • Token validation endpoint: POST /auth/validate in core service returns { valid, user_id, organization_id } for fast WebSocket token checks at upgrade time — 3 tests
  • Procfile: adds core, wrap, communicate, memory, index entries

Closes #1116

@geoffjay geoffjay added the review-agent Used to invoke a review by an agent tracking this label label Apr 16, 2026
@geoffjay
Copy link
Copy Markdown
Owner Author

geoffjay commented Apr 16, 2026

This change is part of the following stack:

Change managed by git-spice.

…date, Procfile

- Add memory (17008), communicate (17010), index (17012) to ProxyConfig::from_env()
  and expand test_proxy_config_defaults / add test_proxy_config_new_service_defaults
- New agentd-common::tenant module: TenantId and OptionalTenantId axum extractors
  that read X-Tenant-ID; AGENTD_REQUIRE_TENANT=true enables strict 400 rejection
- Add POST /auth/validate endpoint to core service: validates bearer token and
  returns { valid, user_id, organization_id } for WebSocket upgrade checks
- Add core, wrap, communicate, memory, index to Procfile

Closes #1116
Copy link
Copy Markdown
Owner Author

@geoffjay geoffjay left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review: feat(auth): gateway completeness, TenantId extractor, POST /auth/validate, Procfile

LGTM — cannot self-approve, posting as comment.

Stack note

This branch (issue-1116) targets feature/core, which itself targets main. It is the direct parent of the entire core migration stack (#1130#1131#1132#1133 / #1134). Those PRs can stack and merge after this one lands.

What was verified

Procfile — 5 new entries; binary names (communicate, agentd-core, agentd-index, memory, wrap) match the package.name convention already used in the file. Alphabetical ordering is preserved across all entries. ✓

crates/common/src/tenant.rs — two Axum extractors:

  • TenantId: header present → wraps value; absent + strict → MissingTenantId (400 JSON); absent + permissive → TenantId(String::new()). Logic is correct; MissingTenantId uses IntoResponse cleanly. ✓
  • OptionalTenantId: Rejection = Infallible, always succeeds, returns Option<String>. ✓
  • Tests: both permissive/strict modes combined in one function to avoid env-var races across parallel test threads — same defensive pattern used in test_get_db_path_respects_agentd_env in storage.rs. ✓

POST /auth/validate — delegates entirely to the existing AuthUser extractor for auth enforcement, so the 401 path requires no new logic (extractor rejects before the handler body runs). The 200 path is a pure read of auth.user fields — no session mutation, no DB write. ✓

  • ValidateResponse.valid is always true in the 200 body (can never be false; invalid tokens produce 401 before reaching the handler). Self-documenting for WebSocket upgrade callers. Acceptable.
  • 3 tests cover: valid token → 200, invalid token → 401, missing token → 401. ✓

crates/core/src/proxy.rs — 3 new entries with port assignments:

  • memory → 17008, communicate → 17010, index → 17012
  • No collisions with existing assignments (17001–17006). Module doc table updated to match. ✓
  • test_proxy_config_new_service_defaults pins the default values; test_proxy_config_all_services extended to include new names. ✓

Non-blocking suggestions

  1. tenant_required() reads the env var on every request. For a hot extractor path this is a small but repeated syscall. A std::sync::OnceLock initialised at first call would be faster and also remove the surprising runtime-change behaviour. Since this is consistent with how AGENTD_ENV is read in get_db_path, no urgency — but worth a follow-up when the tenant module gets wider adoption.

  2. TenantId(String::new()) in permissive mode. Documented, intentional — but service authors using tenant_id.0 as a DB scope key will silently filter by empty string rather than returning all rows or failing. A one-line // NOTE: empty string means no gateway in dev; callers should treat this as "no tenant scope". comment on the None => Ok(TenantId(String::new()))) arm would save future confusion.

@geoffjay geoffjay added merge-queue Approved by reviewer, queued for merge by conductor and removed review-agent Used to invoke a review by an agent tracking this label labels Apr 17, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

merge-queue Approved by reviewer, queued for merge by conductor

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant