Skip to content

feat(auth): IP allow-list — network gating on auth routes (ADR-0069 D5, P2)#2401

Merged
os-zhuang merged 1 commit into
mainfrom
auth/adr-0069-ip-allowlist
Jun 27, 2026
Merged

feat(auth): IP allow-list — network gating on auth routes (ADR-0069 D5, P2)#2401
os-zhuang merged 1 commit into
mainfrom
auth/adr-0069-ip-allowlist

Conversation

@os-zhuang

Copy link
Copy Markdown
Contributor

ADR-0069 P2 / D5 — IP allow-list (network gating).

What

New allowed_ip_ranges auth setting (CIDR ranges or exact IPs, one per line / comma-separated; empty = no restriction). A Hono middleware registered ahead of the better-auth handler in the auth-route registration rejects auth requests from a client IP outside the ranges with 403 IP_NOT_ALLOWED — the exact seam ADR-0069 D5 names.

  • Client IP is read trust-proxy-aware: x-forwarded-for (first hop) → cf-connecting-ipx-real-ip.
  • /config + /bootstrap-status are exempt so a blocked client still gets a clean login page + a clear error (rather than a broken page).
  • Fails OPEN when the client IP can't be determined (no proxy header) — a misconfigured proxy is a no-op, not a lockout. An admin enabling this must ensure forwarded headers are trusted.
  • IPv4 CIDR (a.b.c.d/n) + exact IPv4/IPv6 matching (ipMatchesRange / isClientIpAllowed, unit-tested).

ADR-0049

Default-off / additive (no upgrade behavior change); the setting ships with its enforcement.

Verification

  • Unit: plugin-auth 208 + service-settings 129 green; full build incl. strict DTS green. Tests cover CIDR/exact matching, in-range vs out-of-range, no-ranges-allows-all, and fail-open on undetermined IP.
  • Live dogfood (allowed_ip_ranges=203.0.113.0/24):
    • sign-in with X-Forwarded-For: 8.8.8.8403 IP_NOT_ALLOWED
    • sign-in with X-Forwarded-For: 203.0.113.50200 + token
    • /config from a disallowed IP → 200 (login still renders)
    • no proxy header → 200 (fail-open; admin not locked out)

Scope / follow-ups (#2375)

This gates the auth routes (sign-in / session), per the ADR's D5 seam. Gating all data requests by IP, per-org sys_organization.allowed_ip_ranges, and the require_ip_match session-pinning toggle are follow-ups. Remaining ADR-0069 work: P3 SAML (needs a @better-auth/sso vs custom plugin decision). (OIDC trust-list UI / D6 verified already shipped via the SSO-provider surface.)

🤖 Generated with Claude Code

…5, P2)

- service-settings: new `allowed_ip_ranges` setting (Network group; CIDR/IP list).
- plugin-auth: a Hono middleware registered ahead of the better-auth handler
  rejects auth requests from a client IP outside the ranges with 403
  IP_NOT_ALLOWED. Client IP read trust-proxy-aware (x-forwarded-for first hop /
  cf-connecting-ip / x-real-ip). /config + /bootstrap-status exempt so a blocked
  client still gets a clean login + error. Fails OPEN when the IP can't be
  determined (missing proxy header = no-op, not a lockout). IPv4 CIDR + exact
  match (ipMatchesRange + isClientIpAllowed).

Default-off / additive; ADR-0049.

Verified live (dogfood, allowed=203.0.113.0/24): sign-in with XFF 8.8.8.8 -> 403
IP_NOT_ALLOWED; XFF 203.0.113.50 -> 200 + token; /config from a disallowed IP ->
200 (login renders); no XFF -> 200 (fail-open, admin not locked out). Unit:
plugin-auth 208 + service-settings 129 green; full build incl. strict DTS green.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@vercel

vercel Bot commented Jun 27, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
spec Ready Ready Preview, Comment Jun 27, 2026 6:21pm

Request Review

@github-actions github-actions Bot added documentation Improvements or additions to documentation tests tooling size/m labels Jun 27, 2026
@github-actions

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

This PR changes 2 package(s): @objectstack/plugin-auth, packages/services.

14 hand-written doc(s) reference the affected code and may need an implementation-accuracy re-verification:

  • content/docs/concepts/implementation-status.mdx (via @objectstack/plugin-auth)
  • content/docs/concepts/packages.mdx (via @objectstack/plugin-auth)
  • content/docs/getting-started/cli.mdx (via @objectstack/plugin-auth)
  • content/docs/guides/auth-sso.mdx (via @objectstack/plugin-auth)
  • content/docs/guides/authentication.mdx (via @objectstack/plugin-auth)
  • content/docs/guides/kernel-services.mdx (via @objectstack/plugin-auth)
  • content/docs/guides/packages.mdx (via @objectstack/plugin-auth, packages/services)
  • content/docs/guides/plugins.mdx (via @objectstack/plugin-auth)
  • content/docs/guides/production-readiness.mdx (via @objectstack/plugin-auth)
  • content/docs/guides/runtime-services/audit-service.mdx (via packages/services)
  • content/docs/guides/runtime-services/index.mdx (via packages/services)
  • content/docs/guides/runtime-services/settings-service.mdx (via packages/services)
  • content/docs/protocol/objectos/i18n-standard.mdx (via packages/services)
  • content/docs/releases/v9.mdx (via @objectstack/plugin-auth)

Advisory only. To re-verify, run the docs-accuracy-audit workflow scoped to these files:
node scripts/docs-audit/affected-docs.mjs origin/main → pass the list as args.docs.

@os-zhuang
os-zhuang merged commit 8c84c97 into main Jun 27, 2026
16 checks passed
@os-zhuang
os-zhuang deleted the auth/adr-0069-ip-allowlist branch June 27, 2026 18:21
os-zhuang added a commit that referenced this pull request Jul 13, 2026
feat(plugin-detail,app-shell): Edit as primary CTA; enter inline edit by double-clicking a field (#2401) (#2402)

objectui@839536b1f4c0c0c1853cbc89f832fe7a431b2a9c
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation size/m tests tooling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant