Class AuditController
Reads the audit log over HTTP, authorized identically to the Blazor view and the MCP surface.
[ApiController]
[Route("api/audit")]
[Authorize(Policy = "ThargaApiPolicy")]
public class AuditController : ControllerBase
- Inheritance
-
AuditController
- Inherited Members
Remarks
Read-only by design: nothing about exposing the audit log justifies an endpoint that changes it.
Constructors
AuditController(IAuditReadService, IAuditOversightService)
Reads the audit log over HTTP, authorized identically to the Blazor view and the MCP surface.
public AuditController(IAuditReadService auditReadService, IAuditOversightService auditOversightService)
Parameters
auditReadServiceIAuditReadServiceauditOversightServiceIAuditOversightService
Remarks
Read-only by design: nothing about exposing the audit log justifies an endpoint that changes it.
Methods
GetAsync(string, DateTime?, DateTime?, string, string, bool?, int, int)
Audit entries, newest first.
[HttpGet]
[ProducesResponseType(200)]
[ProducesResponseType(403)]
public Task<ActionResult<AuditQueryResult>> GetAsync(string team = null, DateTime? from = null, DateTime? to = null, string feature = null, string action = null, bool? success = null, int skip = 0, int take = 100)
Parameters
teamstringNarrows a system-audit read to one team. A filter, not an authorization input — it is refused if the caller is already bound to a different team, because that is the same contradiction the header check refuses.
fromDateTime?Earliest timestamp, inclusive.
toDateTime?Latest timestamp, inclusive.
featurestringRestrict to one feature — the left half of a scope, e.g.
apikey.actionstringRestrict to one action — the right half, e.g.
manage.successbool?Restrict to successful or failed entries.
skipintEntries to skip, for paging.
takeintMaximum entries to return. Capped at 500.
Returns
Remarks
There is no team parameter. Which team the call is about comes from the credential: a team
API key is bound to one team and can be nothing else, and a system API key names a team in the
X-Team-Key header when it wants to act on behalf of one. A parameter beside a team-bound
credential would be a second source of truth for one question — they can disagree, and an API
shaped to allow that is wrong even though the disagreement is refused.
A system key with no header reads system audit: every team, narrowed by the filters below —
including team, which narrows data the caller is already authorized for rather
than deciding what to authorize against.