Skip to content

[Policy] Bundled claude-code preset omits platform.claude.com, so the documented Pro/Max browser OAuth login cannot complete #7637

Description

@mill101

Investigation Summary

Hello,
With #7579 fixed (the resolved npm launcher is now allowlisted on main), claude auth login --claudeai gets further but still cannot finish: it fails with Login failed: Socket is closed, and the sandbox denies platform.claude.com:443.
The preset's endpoints list only contains api.anthropic.com, statsig.anthropic.com, and sentry.io. platform.claude.com — where Claude Code exchanges the OAuth authorization code — is absent, so the exchange is refused by the proxy.
This is a different failure class from #7579 and the denial reason string says so: #7579 was binary '...' not allowed in policy 'claude_code', this one is endpoint platform.claude.com:443 is not allowed by any policy. The client-side symptom (Socket is closed) points at neither.
Adding the host to the preset fixes it completely. I first allowed /, then read the L7 log to see what is actually used: only POST /v1/oauth/token. So /v1/oauth/ is sufficient and does not open the rest of the console. Verified working with the narrow scope.
claude.com (the authorization page itself) does not need allowlisting — it is opened in the user's own browser, not from the sandbox. Confirmed across several login attempts by the absence of any denial for it.

Description

What happened

After applying the claude-code preset and installing Claude Code the way the bundled skill documents, claude auth login --claudeai prints the authorization URL and accepts the pasted code, then fails:

Login failed: Socket is closed
claude auth status continues to report {"loggedIn": false, "authMethod": "none"}.

The sandbox log shows the code exchange being denied:

endpoint platform.claude.com:443 is not allowed by any policy
The preset allows exactly three hosts:

endpoints:
  - host: api.anthropic.com
  - host: statsig.anthropic.com
  - host: sentry.io

platform.claude.com is the host Claude Code posts the OAuth authorization code to. It is not in the list, so the browser-based login can never complete.

What I expected

Applying the claude-code preset and following the bundled skill's documented authentication path should let the login finish.

Why this matters

It blocks the authentication method the shipped skill recommends first. ~/.hermes/skills/autonomous-ai-agents/claude-code/SKILL.md (v2.2.0, bundled with Hermes Agent) points Pro/Max subscribers at browser OAuth as the way to authenticate without an API key. The preset then blocks the only network call that path needs.
It is the second half of the same broken path as #7579. #7579 (fixed in #7581) made the binary allowlist correct; a user who applies the fixed preset today still cannot log in, and lands on a new, differently-worded denial. The two together mean the preset as shipped has never been able to authenticate a Pro/Max user.
The failure again does not point at its cause. The CLI only surfaces Socket is closed. The policy-add hint is already satisfied. The real reason appears only in nemoclaw logs.
Suggested fix

Add the host to the preset's endpoints, scoped to the OAuth paths:

  - host: platform.claude.com
    port: 443
    protocol: rest
    enforcement: enforce
    rules:
      - allow: { method: GET, path: "/v1/oauth/**" }
      - allow: { method: POST, path: "/v1/oauth/**" }

This is what I run locally and it is verified working. I deliberately did not use /**: measuring the live flow showed only POST /v1/oauth/token is exercised, so the narrow scope is enough and keeps the rest of the host closed.

For clarity on scope: I am not asking for claude.com (browser-side only, no sandbox egress observed) and not asking for the Datadog telemetry host Claude Code also probes (http-intake.logs.us5.datadoghq.com:443) — that one is denied here and causes no functional problem, so I would leave it closed.

Reproduction Steps

nemoclaw policy-add claude-code --yes (using main, i.e. with #7581 already applied)

Install Claude Code with the method the bundled skill documents. /usr is read-only in the sandbox, so the npm prefix the preset anticipates is used:

nemoclaw exec -- npm install -g --prefix /tmp/npm-global @anthropic-ai/claude-code

Attempt to authenticate:

nemoclaw exec --tty -- /tmp/npm-global/bin/claude auth login --claudeai

Open the printed URL in a browser, authorize, paste the code back.

-> Login failed: Socket is closed

nemoclaw logs --tail 50 shows the denial for platform.claude.com:443.

Confirming the cause:

Add the platform.claude.com block above to nemoclaw-blueprint/policies/presets/claude-code.yaml, then policy-remove claude-code --yes and policy-add claude-code --yes (re-applying the same name without removing first is rejected as "already applied").

Re-run step 3–4. Login completes; claude auth status reports loggedIn: true, authMethod: claude.ai, subscriptionType: pro.

Environment

OS: Windows 11 Pro 26200 + WSL2 (Ubuntu 24.04.4 LTS, kernel 6.6.114.1-microsoft-standard-WSL2)
Node.js: v22.23.1 (host)
npm: 10.9.8 (host)
Docker: Docker Engine 29.4.0
NemoClaw: v0.0.90
OpenShell: 0.0.85
Hermes Agent: v0.18.0 (2026.7.1), Python 3.13.5
Claude Code: 2.1.218
Preset file: nemoclaw-blueprint/policies/presets/claude-code.yaml

Debug Output

Trimmed to the relevant sections — the full bundle also contains unrelated provider and channel configuration for this deployment. Happy to attach it if useful.

═══ System ═══
Linux 6.6.114.1-microsoft-standard-WSL2 x86_64 GNU/Linux
═══ OpenShell ═══
openshell 0.0.85
Gateway: nemoclaw-8990
NAME PHASE
my-hermes Ready
Applied policies:
brew, claude_code, dgx_agent_a1, dgx_nano, dgx_ornith, huggingface,
local_inference, managed_inference, model_switch_hermes,
models_dev_metadata, nous_research, npm_yarn, nvidia, opencode_zen,
openrouter_metadata, pypi, searxng_search, slack
Effective claude_code policy currently in the sandbox (nemoclaw policy-get), i.e. the preset plus the one-host patch this issue asks for:

claude_code:
name: claude_code
endpoints:
- host: api.anthropic.com
port: 443
protocol: rest
enforcement: enforce
rules:
- allow: { method: GET, path: /** }
- allow: { method: POST, path: /** }
- host: platform.claude.com # <-- not in the shipped preset; added locally
port: 443
protocol: rest
enforcement: enforce
rules:
- allow: { method: GET, path: /v1/oauth/** }
- allow: { method: POST, path: /v1/oauth/** }
- host: statsig.anthropic.com
...
Without the middle block — i.e. the preset exactly as shipped on main today — login fails as described.

Logs

Denial captured while reproducing (2026-07-26). The line has the same NET:OPEN ... DENIED shape as the one in #7579; the part that matters is the reason:

endpoint platform.claude.com:443 is not allowed by any policy
Client side, the CLI only ever shows:

Login failed: Socket is closed
Note the contrast with #7579, whose reason string was binary '/tmp/npm-global/lib/node_modules/@anthropic-ai/claude-code/bin/claude.exe' not allowed in policy 'claude_code'. Same preset, same user-visible "it just fails" experience, two unrelated causes — the reason string is the only thing that distinguishes them.

Checklist

Checklist

  • I confirmed this bug is reproducible
  • I searched existing issues and this is not a duplicate

Metadata

Metadata

Assignees

Labels

needs: triageAwaiting maintainer classification

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions