Table of Contents

Class AuditController

Namespace
Tharga.Team.Service.Audit
Assembly
Tharga.Team.Service.dll

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

auditReadService IAuditReadService
auditOversightService IAuditOversightService

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

team string

Narrows 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.

from DateTime?

Earliest timestamp, inclusive.

to DateTime?

Latest timestamp, inclusive.

feature string

Restrict to one feature — the left half of a scope, e.g. apikey.

action string

Restrict to one action — the right half, e.g. manage.

success bool?

Restrict to successful or failed entries.

skip int

Entries to skip, for paging.

take int

Maximum entries to return. Capped at 500.

Returns

Task<ActionResult<AuditQueryResult>>

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.