Files
HiveGrid-Wireframes/hivegrid-cloud/docs/security/route-access-inventory.md
T

16 KiB

Route Access Inventory

This document publishes the checked Hono API route access classification from apps/api/src/route-access-inventory.ts. It is a static security review aid only: it records route boundaries, access classes, rationale, and redacted data-sensitivity notes without changing route handlers, OpenAPI metadata, authorization middleware, or runtime behavior.

Historical-plan note: route keys and access classes in this document are current only when the focused verification below passes. Do not copy route paths from older improvement-plan files into this inventory without confirming the typed source of truth.

Scope and Source of Truth

  • Source of truth: apps/api/src/route-access-inventory.ts.
  • Scanner reference: tools/api-inventory/scan-api-routes.ts discovers app.get/post/patch/delete route registrations from apps/api/src/app.ts for coverage checks.
  • Verification: apps/api/src/route-access-inventory.test.ts checks scanner-discovered route coverage and OpenAPI security expectations; apps/api/src/route-access-inventory-doc.test.ts checks this document for drift.
  • Route keys are written as METHOD path and must match the typed inventory exactly once.
  • This inventory covers all current Hono API routes, including health, documentation, authentication, analytics, accounts, usage, notifications, workspaces, entity, relationship, export, webhook, maintenance, and AI upload surfaces.
  • Adjacent coverage: docs/security/csrf-inventory.md documents CSRF posture and mutating API route classes. This document references that coverage but does not duplicate its mutating-route-only table.

Redaction Rules

  • Do not include tokens, plaintext credentials, fixture tenant identifiers, customer data, environment variable values, or concrete database identifiers.
  • Keep sensitive-data notes categorical and redacted, for example “returns aggregate counts” or “consumes uploaded file content.”
  • Do not paste authorization headers, JWTs, API keys, passwords, emails, tenant fixtures, or customer examples into this document.
  • Route parameters such as :entity, :rowId, and :id are schema placeholders, not real identifiers.

Access Class Legend

Class Boundary
public-health Unauthenticated infrastructure health or readiness endpoint exposing only service/dependency status metadata.
public-docs Unauthenticated API documentation or schema discovery surface exposing schema metadata only.
service-token Service/API-token style boundary, including stored API key or service credential checks where implemented.
service-or-tenant-api-key Service credential or tenant-bound stored API-key boundary with route-specific tenant and permission checks.
optional-api-key-validation Public validation helper that optionally accepts a presented stored API key or service token and returns redacted validation status.
tenant-api-key Tenant-bound stored API-key boundary where the credential scopes the tenant and available usage metadata.
jwt-auth Bearer JWT authenticated user boundary.
auth-credential-exchange Public credential exchange that consumes submitted credentials and issues authenticated API state after validation.
public-analytics-token Public analytics ingress or aggregate read surface scoped by analytics token/payload semantics rather than browser session state.
webhook-signature Signed webhook ingress boundary that verifies provider signing headers before processing an addressed webhook retry.
canonical-redirect Runtime-only compatibility shim that redirects removed API-prefix requests to the canonical API path without reading request data.

Full Route Access Table

Route Access class Sensitive data note Rationale
GET /healthz public-health No sensitive data. Unauthenticated liveness probe returns only service status and request correlation metadata.
GET /readyz public-health Dependency health state is exposed without implementation details. Unauthenticated readiness probe returns redacted dependency status for infrastructure checks.
GET /v1/health public-health No sensitive data. Versioned liveness probe returns only service status and request correlation metadata.
GET /v1/openapi.json public-docs No sensitive data. OpenAPI discovery is intentionally public for client integration and contains schema metadata only.
GET /v1/docs public-docs No sensitive data. Documentation shell is intentionally public and renders the OpenAPI document without runtime data.
GET /v1/session/current-user service-token Returns authenticated principal type metadata only. Current service principal endpoint requires a bearer service token before returning authentication state.
POST /v1/auth/login auth-credential-exchange Consumes credentials and returns a JWT plus basic user identity. Login exchanges submitted email and password credentials for a short-lived JWT after password verification.
POST /v1/auth/refresh-token jwt-auth Returns a JWT plus basic user identity. Refresh requires an existing bearer JWT before issuing a replacement token for the same user.
POST /v1/auth/logout jwt-auth Consumes JWT credential material but returns only a success envelope and expired cookie attributes. Logout requires an existing bearer JWT before revoking the active API session and clearing the API cookie.
POST /v1/api-keys/validate optional-api-key-validation Returns redacted stored API-key metadata but never plaintext key material. API-key validation optionally accepts a presented stored API key or service token and reports redacted validation status without requiring a prior credential.
POST /v1/ai/upload service-token Consumes uploaded file content and may return a public storage URL. AI upload writes request content through configured service storage credentials and depends on server-side upload configuration.
POST /v1/support/inbound-email webhook-signature Consumes signed email metadata and message body while omitting provider payloads and signing material from responses. Inbound support email verifies Mailjet webhook signing headers before resolving tenant inbound addresses and creating tickets.
POST /v1/analytics/events public-analytics-token Consumes analytics identifiers, URLs, routes, and event labels. Analytics event ingestion is public-facing and scoped by analytics payload identifiers rather than browser session state.
POST /v1/analytics/page-views public-analytics-token Consumes analytics identifiers, URLs, and route names. Analytics page-view ingestion is public-facing and scoped by analytics payload identifiers plus ignore-page settings.
GET /v1/analytics/public public-analytics-token Returns aggregate analytics counts and top-level chart data. Public analytics overview requires the analytics token header before returning aggregate metrics.
GET /v1/analytics/admin service-token Returns aggregate analytics metrics that may be scoped to a portal identifier. Admin analytics overview requires service credentials before returning tenant or portal scoped metrics.
GET /v1/notifications/stream service-token Returns bounded, sanitized notification delivery snapshots and cursors without provider payloads, metadata, or raw delivery secrets. Notification stream requires service credentials before returning tenant and user scoped in-app delivery diagnostics over SSE.
GET /v1/accounts service-token Returns tenant identifiers, names, slugs, icons, and subscription summary fields without plaintext secrets. Account listing requires service credentials before returning tenant account metadata and subscription summaries.
GET /v1/accounts/:id service-token Returns tenant identifiers, names, slugs, icons, and subscription summary fields without plaintext secrets. Account lookup requires service credentials before returning one tenant account metadata and subscription summary.
GET /v1/usage tenant-api-key Returns plan and remaining API usage metadata for the credential-scoped tenant. Usage lookups enter through the canonical API host and validate tenant API-key credentials in the API runtime.
POST /v1/billing/stripe/webhooks webhook-signature Consumes signed billing lifecycle webhook payloads without returning signing material or plaintext credentials. Stripe billing webhook ingress enters through the canonical API host and verifies the raw signed payload in the API runtime.
POST /v1/email-sequences/mailjet/webhooks webhook-signature Consumes signed delivery event metadata while responses omit provider payloads, recipient data, and signing material. Email-sequence provider webhooks verify Mailjet signing headers before correlating bounce events to provider message ids.
GET /v1/workspaces/:tenantId/auth/providers service-token Returns redacted OIDC/SAML provider metadata only; client secrets, SAML certificate bodies, private keys, token hashes, invite tokens, and raw metadata documents are omitted. Workspace auth-provider discovery requires a service token before returning tenant-scoped SSO metadata.
POST /v1/workspaces/:tenantId/context/revalidate service-token Consumes tenant and user identifiers and returns a redacted validity envelope without provider secrets, invite tokens, token hashes, or SSO secret material. Workspace context revalidation requires a service token before confirming tenant/user membership for a context switch.
GET /v1/workspaces/:tenantId/invites service-token Returns invite recipient details, lifecycle timestamps, audit user ids, and tokenPrefix only; plaintext tokens and token hashes are omitted. Workspace invite listing requires a service token before returning tenant-scoped invite lifecycle state.
POST /v1/workspaces/:tenantId/invites service-token Consumes invite recipient details and returns the one-time plaintext invite token only in the create response. Workspace invite creation requires a service token before issuing a tenant-scoped invite token.
POST /v1/workspaces/:tenantId/invites/:inviteId/accept service-token Consumes plaintext invite token and returns redacted invite lifecycle metadata without echoing the token. Workspace invite acceptance requires a service token and a one-time invite token before finalizing tenant membership invitation state.
POST /v1/workspaces/:tenantId/invites/:inviteId/revoke service-token Consumes revoke audit metadata and returns redacted invite lifecycle metadata without token material. Workspace invite revocation requires a service token before finalizing the tenant-scoped invite as revoked.
POST /v1/events/webhooks/attempts/:id webhook-signature Consumes signed webhook delivery metadata and an attempt id while omitting provider payloads and signing material from responses. Webhook retry verifies Mailjet webhook signing headers before looking up or queueing a known delivery attempt.
POST /v1/maintenance/export-retention/enqueue service-token Consumes an optional bounded batch size and returns only queue task metadata plus request correlation. Export artifact retention cleanup is an operator maintenance action and requires service credentials before enqueueing work.
GET /v1/entities/:entity/rows service-or-tenant-api-key Returns tenant-scoped legacy entity row data. Entity row listing requires a service token or scoped stored API key with read permission for the resolved entity.
POST /v1/entities/:entity/rows service-or-tenant-api-key Consumes and stores tenant-scoped legacy entity row data. Entity row creation requires a service token or scoped stored API key with create permission for the resolved entity.
GET /v1/entities/:entity/rows/:rowId service-or-tenant-api-key Returns tenant-scoped legacy entity row data. Entity row lookup requires a service token or scoped stored API key with read permission for the resolved entity.
PATCH /v1/entities/:entity/rows/:rowId service-or-tenant-api-key Consumes and returns tenant-scoped legacy entity row data. Entity row update requires a service token or scoped stored API key with update permission for the resolved entity.
DELETE /v1/entities/:entity/rows/:rowId service-or-tenant-api-key Deletes tenant-scoped legacy entity row data and returns the deleted row id. Entity row deletion requires a service token or scoped stored API key with delete permission for the resolved entity.
POST /v1/relationships service-or-tenant-api-key Consumes row identifiers and returns relationship metadata. Relationship creation requires a service token or scoped stored API key with create permission for both related entities.
GET /v1/relationships/:id service-or-tenant-api-key Returns relationship metadata with parent and child row envelopes. Relationship lookup requires a service token or scoped stored API key with read permission for both related entities.
DELETE /v1/relationships/:id service-or-tenant-api-key Deletes and returns relationship metadata with parent and child row envelopes. Relationship deletion requires a service token or scoped stored API key with delete permission for both related entities.
GET /v1/exports/:exportJobId/download-url service-or-tenant-api-key Returns a signed artifact URL envelope without artifact bucket/key values, storage credentials, pause reason internals, filters, or object bodies. Export download URL creation requires service credentials or a tenant-bound stored API key and blocks compliance-paused exports before returning a short-lived signed artifact URL envelope.
GET /v1/exports/:exportJobId/progress service-or-tenant-api-key Returns export progress envelope (status, percent, rowCount) — no artifact URLs, no compliance-pause internals, no filters. Export progress polling requires service credentials or a tenant-bound stored API key; the handler scopes lookups to the caller's tenant and never leaks artifact bucket/key details.
POST /v1/devices/register service-token Persists device-bound push token. Stored token is hashed at rest; response contains only the registration id + masked token preview. Mobile push-token registration requires a service credential (bearer/API-key) carrying user identity; the body's userId + tenantId are reconciled against the authenticated principal downstream.
POST /v1/devices/revoke service-token Returns revocation confirmation without echoing the device token or push provider internals. Mobile push-token revocation requires a service credential; the handler revokes by token hash and never echoes the raw token.
GET /v1/entities/:entity service-token Returns legacy entity schema and relationship details. Legacy entity lookup requires service credentials before returning the named entity detail graph.
GET /status public-health Boolean health state and deployment region tag only — no connection strings, hostnames or stack traces. Unauthenticated status probe for external uptime monitors. Returns boolean-only health, revision, region, uptime.
GET /metrics service-token Prom text-format counters and gauges — includes business KPIs (AI tokens, mail, webhook, queue depth). Token-protected. Prometheus scrape endpoint requires bearer METRICS_TOKEN. Returns 404 when METRICS_ENABLED is false.

Verification Commands

Run focused verification from the repository root after changing Hono routes, OpenAPI security metadata, the typed route access inventory, or this document:

pnpm exec vitest run apps/api/src/route-access-inventory.test.ts apps/api/src/route-access-inventory-doc.test.ts
pnpm exec eslint apps/api/src/route-access-inventory.ts apps/api/src/route-access-inventory.test.ts apps/api/src/route-access-inventory-doc.test.ts --max-warnings=0

Expected diagnostics name stale or missing route keys in METHOD path form, OpenAPI security drift, redaction matches, and missing required section headings by heading text.