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

vercelBot commented Jun 27, 2026

Copy link
Copy Markdown

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

ProjectDeploymentActionsUpdated (UTC)
specReadyReadyPreview, CommentJun 27, 2026 6:21pm

Request Review

@github-actionsgithub-actionsBot 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 mainJun 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 freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentationImprovements or additions to documentationsize/mteststooling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@os-zhuang