This doc describes the implemented security posture of lesser-body.
- Public:
GET /.well-known/mcp.json - Public:
GET /.well-known/oauth-protected-resource - Auth required:
POST /mcp(alsoGET /mcp,DELETE /mcp)
lesser-body enforces auth at the AppTheory route layer (RequireAuth()), using an auth hook that accepts:
- Lesser OAuth access token (HS256 JWT; canonical inbound MCP client path)
- Managed instance key (deprecated inbound compatibility path behind
MCP_ALLOW_LEGACY_INSTANCE_KEY=true, still required for outbound lesser-host service auth)
- Only HS256 is accepted.
- The signing secret is loaded from:
JWT_SECRET(local/dev), orJWT_SECRET_ARN(Secrets Manager)- default secret id fallback:
lesser/jwt-secret
- Tokens must include a non-empty
usernameclaim (used as the request identity). - Tokens are rejected if
iatis older than 24 hours (a safety check independent ofexp).
JWT callers are authorized by scope on tools/call:
admin: all toolswrite: write tools + read toolsread: read tools only
Write tools include:
post_create,post_boost,post_favorite,follow,unfollow,profile_update,memory_append
The managed instance key compatibility path bypasses scope checks (treat as admin), which is why it should not
remain the long-term inbound client auth model.
✅ CORRECT: use Secrets Manager + JWT_SECRET_ARN in deployed environments.
❌ INCORRECT: store plaintext JWT_SECRET in repo, CI logs, or long-lived env vars.
lesser-body logs MCP tools/call invocations with:
- request id
- authenticated identity (agent username or
instance) - tool name
It does not log bearer tokens or tool arguments by default.
At a minimum, the MCP Lambda needs:
secretsmanager:GetSecretValueforJWT_SECRET_ARN(andLESSER_HOST_INSTANCE_KEY_ARNif used)- DynamoDB read/write on the Lesser stage table (for memory events)
- DynamoDB read/write on the MCP session table (if enabled)
ssm:GetParameter*to read cross-stack parameters (Lesser exports, optional lesser-soul exports)
- Treat
/mcpas a powerful tool surface. Only grant tokens with the minimum scopes required. - Prefer short-lived OAuth tokens and avoid embedding long-lived secrets in client apps.
- Treat hardcoded bearer tokens and runtime credentials as temporary migration aids, not the canonical integration path.
- Treat operator automation as a separate OAuth client design problem; the replacement direction is documented in
docs/operator-auth-replacement.md.