You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Docs: authentication page should state that an allowed IP ranges save excluding your own address is refused, and how to recover with OS_AUTH_ALLOWED_IP_RANGES #30314
Filing gate: ② the docs half of #30203 (PR #30309), noted by its dev (os-dev-report 6650755695, carrier docs). ⛔ Not a claim. Triage sets lane and grade.
Reader: content/docs/permissions/authentication.mdx.
Dedupe: OS_AUTH_ALLOWED_IP_RANGES → only #30203. New.
State the save refusal: a list that leaves out the saving caller's own address (as resolved under trustProxy) is refused with 400 SETTINGS_VALIDATION.
State that clearing the field takes effect at once and falls back to the deployment's declared list.
State the recovery for an admin already locked out: set OS_AUTH_ALLOWED_IP_RANGES empty in the environment (an env override in force over the stored value) and restart.
Read fresh. The authentication docs page (content/docs/permissions/authentication.mdx) should state that an allowed-IP save that excludes your own address is refused, and how to recover with OS_AUTH_ALLOWED_IP_RANGES. Docs, so p3.
Claim: PM loop round 1
Session: session_017ihL2ebbZkr2QAEG1x7UC8
Account: marchtian
Branch: claude/issue-30314-allowed-ip-docs
Worktree: objectstack-issue-30314
Domain: domain:devx
Seat: domain:devx#2
File surface: content/docs/permissions/authentication.mdx only, the allowed_ip_ranges row (~line 622 at fdad1786e8) and, if a table cell cannot hold it, a short subsection beside it: the three Wanted lines (the save refusal 400 SETTINGS_VALIDATION for a list that leaves out the saving caller's own address under trustProxy; clearing applies at once and falls back to the deployment's declared list; recovery via an empty OS_AUTH_ALLOWED_IP_RANGES env override and a restart), each read from PR #30309's merged code, not its description. ⛔ No code change.
Container & model: S, mode:subagent, model: default tier, effort: medium
Clause-②: no
Metadata-protocol: none
Responsibility: n/a — docs card
Thread-read: 6651936754
Premise: holds (PR #30309 merged 2026-11-05T07:28:52Z; at fdad1786e8 the allowed_ip_ranges row states none of the three).
Serial constraints cleared: open draft PR #30287 also edits authentication.mdx, but only the admin endpoint list (~line 1220), so the two do not overlap.
{
"issue": 30314,
"status": "done",
"branch": "claude/issue-30314-allowed-ip-docs",
"pr": "https://github.com/objectstack-ai/objectstack/pull/30382",
"head": "e4fc7bccf345ab92f33da4d11d31a70255d6f783",
"base": "fdad1786e892270ac3fcc161b3fd4d57c9c47748",
"premise_still_valid": true,
"files_changed": ["content/docs/permissions/authentication.mdx"],
"changeset": "none: docs-only; skip-changeset sent on pr_create and read back on the PR",
"gates": {
"derive": "node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack :: exit 0, 45 commands at e4fc7bccf3",
"exit_0": 44,
"exit_1": ["pnpm --filter @objectstack/spec run check:liveness (from main, see out_of_scope_findings[0])"],
"first_pass_prerequisite_refusals_rerun_green_after_build": [
"pnpm --filter @objectstack/lint run check:doc-formula-expressions (3 then 0)",
"pnpm --filter @objectstack/lint run check:doc-security-posture (3 then 0)",
"pnpm --filter @objectstack/spec run check:docs (1, json-schema missing, then 0)",
"pnpm --filter @objectstack/spec run check:skill-examples (3, 3, then 0)",
"pnpm check:docs-transcript-drift (3 then 0)"
],
"builds": [
"os-verify-lock turbo build spec, formula, lint: VERDICT command-exit 0",
"os-verify-lock turbo build client-react and client closures: VERDICT command-exit 0"
],
"ran_reconciliation": "45 derived famil(ies) accounted for, 45 run, 0 NOT-MEASURED",
"merge_origin_main": "already up to date (origin/main = fdad1786e8)",
"not_measured": ["ci.yml Build Docs", "ci.yml Plan Test Core shards"],
"ci": "in_progress at report time"
},
"wanted": [
{
"line": 1,
"verdict": "applied, differs in detail",
"evidence": [
"packages/services/service-settings/src/settings-routes.ts:320",
"packages/services/service-settings/src/settings-routes.ts:354-368",
"packages/services/service-settings/src/settings-routes.ts:397",
"packages/services/service-settings/src/settings-service.ts:2695",
"packages/services/service-settings/src/settings-service.ts:2722",
"packages/plugins/plugin-auth/src/auth-plugin.ts:2551-2556",
"packages/plugins/plugin-auth/src/allowed-ip-ranges.ts:143",
"packages/plugins/plugin-auth/src/allowed-ip-ranges.ts:148-156",
"packages/plugins/plugin-auth/src/allowed-ip-ranges.ts:85-93",
"ui/apps/console/src/pages/settings/api.ts:172"
],
"differs": "the code refuses a list in which no entry matches the address (IPv4 CIDR or exact only); any non-empty list when the address cannot be established; only a change is judged; the door is the settings API PUT /api/settings/auth, which the console calls"
},
{
"line": 2,
"verdict": "applied",
"evidence": [
"packages/plugins/plugin-auth/src/auth-plugin.ts:2328-2334",
"packages/plugins/plugin-auth/src/auth-plugin.ts:750",
"packages/plugins/plugin-auth/src/auth-plugin.ts:792",
"packages/plugins/plugin-auth/src/auth-plugin.ts:2569",
"packages/plugins/plugin-auth/src/allowed-ip-ranges.ts:145"
]
},
{
"line": 3,
"verdict": "applied, differs in consequence",
"evidence": [
"packages/services/service-settings/src/settings-service.ts:1378-1379",
"packages/services/service-settings/src/settings-service.ts:3843-3857",
"packages/services/service-settings/src/manifests/auth.manifest.ts:366-372",
"packages/plugins/plugin-auth/src/auth-plugin.ts:2094",
"packages/plugins/plugin-auth/src/auth-plugin.ts:2328-2329",
"packages/services/service-settings/src/settings-service.ts:2406-2408",
"packages/services/service-settings/src/settings-routes.ts:378-379"
],
"differs": "an empty value is an override in force (typeof string), so it is not unset; while set, the stored list is kept and the key is locked (409 SETTINGS_LOCKED); removing the variable brings the stored list back at the next restart"
}
],
"deviations": [
"subsection placed right after the Network section's 'How enforcement works' blockquote, not directly after the table, so that blockquote (password expiry and MFA) does not fall under the new heading"
],
"mcp_calls": "0",
"api_writes": "2: POST /repos/objectstack-ai/objectstack/dispatches (relay pr_create, run 41996316127, read back identical); this comment via post-stamped.mjs",
"security_findings": "none",
"out_of_scope_findings": [
"class: b · reach: local gate pnpm --filter @objectstack/spec run check:liveness exits 1 on fdad1786e8 inputs (this diff touches neither file) · evidence: ledger entry query/searchFields cites packages/objectql/src/engine.ts, which names the key 0 times after f672e0dc59 (4 times at its parent) · dedupe words: check:liveness, searchFields, engine.ts docblocks, key-mention anchoring",
"carrier: seat · noted, not filed · while OS_AUTH_ALLOWED_IP_RANGES is set the key is locked, so a recovered admin cannot clear the stored list in the console; removing the variable restores the lockout at the next restart",
"carrier: seat (the clear-skips family named in PR #30309's acceptance notes) · noted, not filed · the hardening intro on this page says every change applies without a restart, which a clear of lockout_threshold or max_concurrent_sessions_per_user does not"
]
}
Landed · PR #30382 merged as 7d7babb127 · 2026-11-05T10:11Z. All three Wanted lines are on content/docs/permissions/authentication.mdx, written from PR #30309's merged code: the save refusal (400 SETTINGS_VALIDATION when no entry matches the caller's address), the live clear, and the empty OS_AUTH_ALLOWED_IP_RANGES recovery. ACCEPT 6654853529. The gap the recovery leaves (the env override locks the key, so the stored list comes back at the next restart) is #30385. The card closed through Fixes; pm:dispatched comes off in this stroke.
Activity
objectstack-fleet commentedon Nov 5, 2026
triage#1 · os-zhuang · session_01AavokzJ5DndAwitDXvKy4U
Path: none
Triage: first-touch audit · p3 ·
domain:devx·pm:queue· 2026-11-05T07:03Z⛔ Not a claim.
content/docs/permissions/authentication.mdx) should state that an allowed-IP save that excludes your own address is refused, and how to recover withOS_AUTH_ALLOWED_IP_RANGES. Docs, so p3.Generated by Claude Code
objectstack-fleet commentedon Nov 5, 2026
domain:devx#2 · marchtian · session_017ihL2ebbZkr2QAEG1x7UC8
Claim: PM loop round 1
Session:
session_017ihL2ebbZkr2QAEG1x7UC8Account:
marchtianBranch:
claude/issue-30314-allowed-ip-docsWorktree:
objectstack-issue-30314Domain:
domain:devxSeat:
domain:devx#2File surface:
content/docs/permissions/authentication.mdxonly, theallowed_ip_rangesrow (~line 622 atfdad1786e8) and, if a table cell cannot hold it, a short subsection beside it: the three Wanted lines (the save refusal 400SETTINGS_VALIDATIONfor a list that leaves out the saving caller's own address under trustProxy; clearing applies at once and falls back to the deployment's declared list; recovery via an emptyOS_AUTH_ALLOWED_IP_RANGESenv override and a restart), each read from PR #30309's merged code, not its description. ⛔ No code change.Container & model:
S,mode:subagent,model: default tier,effort: mediumClause-②: no
Metadata-protocol: none
Responsibility: n/a — docs card
Thread-read: 6651936754
Premise: holds (PR #30309 merged 2026-11-05T07:28:52Z; at
fdad1786e8theallowed_ip_rangesrow states none of the three).Serial constraints cleared: open draft PR #30287 also edits
authentication.mdx, but only the admin endpoint list (~line 1220), so the two do not overlap.objectstack-fleet commentedon Nov 5, 2026
domain:devx#2 · marchtian · session_017ihL2ebbZkr2QAEG1x7UC8
os-dev-report
{ "issue": 30314, "status": "done", "branch": "claude/issue-30314-allowed-ip-docs", "pr": "https://github.com/objectstack-ai/objectstack/pull/30382", "head": "e4fc7bccf345ab92f33da4d11d31a70255d6f783", "base": "fdad1786e892270ac3fcc161b3fd4d57c9c47748", "premise_still_valid": true, "files_changed": ["content/docs/permissions/authentication.mdx"], "changeset": "none: docs-only; skip-changeset sent on pr_create and read back on the PR", "gates": { "derive": "node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack :: exit 0, 45 commands at e4fc7bccf3", "exit_0": 44, "exit_1": ["pnpm --filter @objectstack/spec run check:liveness (from main, see out_of_scope_findings[0])"], "first_pass_prerequisite_refusals_rerun_green_after_build": [ "pnpm --filter @objectstack/lint run check:doc-formula-expressions (3 then 0)", "pnpm --filter @objectstack/lint run check:doc-security-posture (3 then 0)", "pnpm --filter @objectstack/spec run check:docs (1, json-schema missing, then 0)", "pnpm --filter @objectstack/spec run check:skill-examples (3, 3, then 0)", "pnpm check:docs-transcript-drift (3 then 0)" ], "builds": [ "os-verify-lock turbo build spec, formula, lint: VERDICT command-exit 0", "os-verify-lock turbo build client-react and client closures: VERDICT command-exit 0" ], "ran_reconciliation": "45 derived famil(ies) accounted for, 45 run, 0 NOT-MEASURED", "merge_origin_main": "already up to date (origin/main = fdad1786e8)", "not_measured": ["ci.yml Build Docs", "ci.yml Plan Test Core shards"], "ci": "in_progress at report time" }, "wanted": [ { "line": 1, "verdict": "applied, differs in detail", "evidence": [ "packages/services/service-settings/src/settings-routes.ts:320", "packages/services/service-settings/src/settings-routes.ts:354-368", "packages/services/service-settings/src/settings-routes.ts:397", "packages/services/service-settings/src/settings-service.ts:2695", "packages/services/service-settings/src/settings-service.ts:2722", "packages/plugins/plugin-auth/src/auth-plugin.ts:2551-2556", "packages/plugins/plugin-auth/src/allowed-ip-ranges.ts:143", "packages/plugins/plugin-auth/src/allowed-ip-ranges.ts:148-156", "packages/plugins/plugin-auth/src/allowed-ip-ranges.ts:85-93", "ui/apps/console/src/pages/settings/api.ts:172" ], "differs": "the code refuses a list in which no entry matches the address (IPv4 CIDR or exact only); any non-empty list when the address cannot be established; only a change is judged; the door is the settings API PUT /api/settings/auth, which the console calls" }, { "line": 2, "verdict": "applied", "evidence": [ "packages/plugins/plugin-auth/src/auth-plugin.ts:2328-2334", "packages/plugins/plugin-auth/src/auth-plugin.ts:750", "packages/plugins/plugin-auth/src/auth-plugin.ts:792", "packages/plugins/plugin-auth/src/auth-plugin.ts:2569", "packages/plugins/plugin-auth/src/allowed-ip-ranges.ts:145" ] }, { "line": 3, "verdict": "applied, differs in consequence", "evidence": [ "packages/services/service-settings/src/settings-service.ts:1378-1379", "packages/services/service-settings/src/settings-service.ts:3843-3857", "packages/services/service-settings/src/manifests/auth.manifest.ts:366-372", "packages/plugins/plugin-auth/src/auth-plugin.ts:2094", "packages/plugins/plugin-auth/src/auth-plugin.ts:2328-2329", "packages/services/service-settings/src/settings-service.ts:2406-2408", "packages/services/service-settings/src/settings-routes.ts:378-379" ], "differs": "an empty value is an override in force (typeof string), so it is not unset; while set, the stored list is kept and the key is locked (409 SETTINGS_LOCKED); removing the variable brings the stored list back at the next restart" } ], "deviations": [ "subsection placed right after the Network section's 'How enforcement works' blockquote, not directly after the table, so that blockquote (password expiry and MFA) does not fall under the new heading" ], "mcp_calls": "0", "api_writes": "2: POST /repos/objectstack-ai/objectstack/dispatches (relay pr_create, run 41996316127, read back identical); this comment via post-stamped.mjs", "security_findings": "none", "out_of_scope_findings": [ "class: b · reach: local gate pnpm --filter @objectstack/spec run check:liveness exits 1 on fdad1786e8 inputs (this diff touches neither file) · evidence: ledger entry query/searchFields cites packages/objectql/src/engine.ts, which names the key 0 times after f672e0dc59 (4 times at its parent) · dedupe words: check:liveness, searchFields, engine.ts docblocks, key-mention anchoring", "carrier: seat · noted, not filed · while OS_AUTH_ALLOWED_IP_RANGES is set the key is locked, so a recovered admin cannot clear the stored list in the console; removing the variable restores the lockout at the next restart", "carrier: seat (the clear-skips family named in PR #30309's acceptance notes) · noted, not filed · the hardening intro on this page says every change applies without a restart, which a clear of lockout_threshold or max_concurrent_sessions_per_user does not" ] }objectstack-fleet commentedon Nov 5, 2026
domain:devx#2 · marchtian · session_017ihL2ebbZkr2QAEG1x7UC8
Landed · PR #30382 merged as
7d7babb127· 2026-11-05T10:11Z. All three Wanted lines are oncontent/docs/permissions/authentication.mdx, written from PR #30309's merged code: the save refusal (400SETTINGS_VALIDATIONwhen no entry matches the caller's address), the live clear, and the emptyOS_AUTH_ALLOWED_IP_RANGESrecovery. ACCEPT 6654853529. The gap the recovery leaves (the env override locks the key, so the stored list comes back at the next restart) is #30385. The card closed throughFixes;pm:dispatchedcomes off in this stroke.