Skip to content
This repository was archived by the owner on Jul 19, 2026. It is now read-only.
This repository was archived by the owner on Jul 19, 2026. It is now read-only.

Anonymous sandbox tier: serve limited features without authentication #42

Description

@haasonsaas

Problem

Currently, an unauthenticated request to /mcp returns 401. This means the agent gets nothing until auth completes. For the OAuth browser flow, that's a few seconds. But for agents in headless environments without federation credentials, it's a dead end.

Insight

npm doesn't require signup before npm install. Docker Hub serves pulls without auth. PyPI works anonymously. The value comes first, the account comes when you need to publish.

Proposed implementation

Unauthenticated agents get a sandbox session

When no Authorization header is present AND no provider credentials are detected in the federation paths:

  1. Issue an anonymous session (stored in the session store with a session_type: "anonymous" flag)
  2. Rate limit: 10 tool calls/minute, 100/hour per IP
  3. Session TTL: 1 hour (no heartbeat renewal)

Anonymous tool access

Tool Anonymous Authenticated
evalops_register ❌ Returns step-up auth instructions ✅ Full registration
evalops_heartbeat ❌ N/A ✅ Token rotation
evalops_check_action ⚠️ Dry-run mode (returns classification but doesn't enforce) ✅ Full governance
evalops_check_approval ❌ No approval creation ✅ Full approvals
evalops_report_usage ❌ Not recorded ✅ Full metering

Anonymous resource access

Resource Anonymous Authenticated
evalops://agent/instructions ✅ Full protocol doc ✅ Same
evalops://agent/operating-rules ✅ Public rules only ✅ All scoped rules
evalops://agent/habits ✅ Read-only, workspace defaults ✅ Full workspace habits
evalops://agent/status ✅ Shows anonymous session info ✅ Full agent status
evalops://agent/hook-requirements ✅ Same ✅ Same

Step-up auth on write operations

When an anonymous session tries a gated operation:

{
  "error": "authentication_required",
  "message": "This action requires authentication. Set ANTHROPIC_API_KEY, OPENAI_API_KEY, or GITHUB_TOKEN in your environment, or call evalops_register with a user_token.",
  "upgrade_options": [
    {"method": "federation", "env_vars": ["ANTHROPIC_API_KEY", "OPENAI_API_KEY", "GITHUB_TOKEN"]},
    {"method": "oauth", "url": "https://mcp.evalops.dev/.well-known/oauth-protected-resource"},
    {"method": "api_key", "header": "Authorization: Bearer pk_..."}
  ]
}

This tells the agent (and the human reading the agent's output) exactly how to upgrade.

Why this matters

The agent gets value on first contact:

  • Reads the governance protocol and operating rules → knows how to behave
  • Runs dry-run governance checks → understands risk classification without enforcement
  • Sees approval habits → understands the workspace's patterns

This is the difference between "connect and learn" vs "connect and get blocked." The agent starts understanding the control plane before it has permission to be governed by it. When auth happens (via federation, OAuth, or API key), the agent already knows the rules.

Security considerations

  • Anonymous sessions get NO workspace context (no org_id). They see only public/default rules.
  • Dry-run governance checks are logged but not enforced — no actual policy decisions for anonymous agents
  • Anonymous sessions cannot create, modify, or delete any persistent state
  • Rate limiting by IP prevents abuse
  • Anonymous sessions are not published to NATS (no event bus pollution)
  • The session store tracks anonymous sessions separately for monitoring

The friction spectrum after this change

Scenario Friction
Agent has provider API key in env Zero — federation, auto-provision, immediate full access
Agent has no credentials, human available One click — OAuth browser flow
Agent has no credentials, headless Read-only sandbox — still gets value, knows how to upgrade

References

  • npm registry anonymous access as design model
  • MCP spec: authorization is OPTIONAL
  • internal/http/router.go — current auth middleware
  • internal/session/ — session store (add anonymous session type)
  • internal/tools/ — per-tool auth gating

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions