"""Identity a tool call runs as. Admin-token mode uses the configured ``GITEA_TOKEN`` (stdio, or the static MCP bearer on HTTP). OAuth mode uses the signed-in user's own Gitea token. The identity travels with each call so the executor can pick the right token and the result envelope and audit log can name who acted. """ from __future__ import annotations from dataclasses import dataclass, field from typing import Any, Literal IdentityMode = Literal["admin-token", "oauth"] @dataclass(frozen=True) class Identity: """Who a tool call acts as. Attributes: login: Gitea login when known (``None`` until resolved). mode: ``admin-token`` or ``oauth``. token: Gitea token for this identity. Excluded from ``repr`` and never part of :meth:`metadata`. redact: Further secrets of this identity (for example the OAuth user's Gitea refresh token) that the executor replaces in every result. Excluded from ``repr`` and comparisons. """ login: str | None mode: IdentityMode token: str = field(repr=False) redact: tuple[str, ...] = field(default=(), repr=False, compare=False) def metadata(self, sudo: str | None = None) -> dict[str, Any]: """Return result and audit metadata: ``{"login", "mode", "sudo"}``, never the token.""" return {"login": self.login, "mode": self.mode, "sudo": sudo}