Skip to content

docs service: system token fails open when SOS_DOCS_TOKEN unset #207

Description

@servathadi

Summary

sos/services/docs/app.py:125 has the identical fail-open shape that
sos/services/squad/auth.py's P0-A finding closed on the squad surface —
found out-of-delta by adversarial gate-4 on PR #205
(/home/mumega/mupot-worktrees/_gate-verdicts/sos-205-790a2a63-gate4.md,
kasra-review, Opus 5, 2026-07-27).

# sos/services/docs/app.py:85
_SYSTEM_TOKEN: str = os.getenv("SOS_DOCS_TOKEN", "")
# sos/services/docs/app.py:125  (_resolve_caller)
is_system = raw_token == _SYSTEM_TOKEN

raw_token is authorization[7:].strip(), so Authorization: Bearer
(empty bearer) yields "". With SOS_DOCS_TOKEN unset, _SYSTEM_TOKEN
defaults to "" too, so "" == ""is_system=True — an unauthenticated
caller with no real credential gets the system tier on this service.
Byte-for-byte the bug the squad service's P0-A fix (sos-205-47f5f8c2)
closed, in a sibling service that was untouched by that delta.

Note: _caller_from_token at line 101 (a different code path in the same
file) already has an if not token: return CallerContext() guard and is
NOT affected — only _resolve_caller's is_system line at 125 is fail-open.

Fix

Same shape as the squad fix — gate on presence, then compare bytes (to also
avoid the BLOCK-A non-ASCII hmac.compare_digest crash class found in the
same gate, see sos/services/squad/auth.py:_lookup_token's comment for the
rationale):

is_system = bool(_SYSTEM_TOKEN) and hmac.compare_digest(
    raw_token.encode("utf-8"), _SYSTEM_TOKEN.encode("utf-8")
)

Add a startup warning when SOS_DOCS_TOKEN is unset (mirroring
sos/services/squad/auth.py's logger.warning on import), and a unit test
driving _resolve_caller/_caller_from_token directly with SOS_DOCS_TOKEN
genuinely unset (fake HOME so no .env.secrets masks it) plus a non-ASCII
bearer, matching the two regression classes closed on the squad surface in
PR #205.

Scope

Out of PR #205's delta (the docs service is untouched by that PR) — not a
reason to block #205, filed separately per the gate-4 verdict's directive.

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