.NET API
IRunAuthorizationHandler
Tracon.Abstractions.dllDecides whether a caller may start a run or read/write a session.
public interface IRunAuthorizationHandlerRemarks
Section titled “Remarks”Tracon draws ownership at the TENANT level. Without this handler, every
Operator in a tenant can start a run as, read, and delete every
other user’s runs and sessions in the same tenant. This interface does not
teach Tracon that boundary — it asks the consumer to enforce their own.
One narrower boundary IS built in, for sessions only: TraconSessionOwnershipOptions records which user opened a session and narrows the session listing to that user. It is off by default, and it does not replace this handler — it answers “which user owns this session” so that a handler no longer has to reject a whole listing just to keep users apart, and leaves every other question (runs, attachments, approvals, scores, per-project rules) to the consumer’s own policy. The two compose: both are consulted, and either can refuse.
The default implementation (AllowAllRunAuthorizationHandler,
registered with TryAdd) allows every call, so an installation that
registers nothing keeps today’s behavior exactly. A consumer replaces the
registration to enforce their own rule.
If this handler throws, the call is denied (fail-closed). A gate that fails open on an exception is not a gate. The same rule IToolAuthorizationHandler follows.
The implementation must be a singleton, for the same
reason as IRunAttributionContext: singleton services take a
dependency on it, and a scoped registration would be a captive dependency.
Resolve per-request state through IHttpContextAccessor.
Tenant mode: expected tenant. Every request carries its own
TenantId, resolved by the caller before the handler is invoked; the
handler never reads ITenantContext itself. This is deliberate:
a queued run’s authorization is checked before the tenant’s ambient scope
(AmbientTenantScope) is necessarily active.
Delivery guarantee: no delivery guarantee applies. This is a synchronous decision, not a retried or queued operation — each call is made once, on the request thread, and its result is not persisted or replayed.
Methods
Section titled “Methods”AuthorizeRunAsync(RunAuthorizationRequest, CancellationToken)
Section titled “ AuthorizeRunAsync(RunAuthorizationRequest, CancellationToken)”Decides whether the run described by request may start.
ValueTask<RunAuthorizationResult> AuthorizeRunAsync(RunAuthorizationRequest request, CancellationToken cancellationToken = default)Parameters
Section titled “Parameters”request RunAuthorizationRequest
The run being authorized.
cancellationToken CancellationToken
The cancellation token.
Returns
Section titled “Returns”ValueTask<RunAuthorizationResult>
The decision.
AuthorizeSessionAsync(SessionAuthorizationRequest, CancellationToken)
Section titled “ AuthorizeSessionAsync(SessionAuthorizationRequest, CancellationToken)”Decides whether the session access described by request may proceed.
ValueTask<RunAuthorizationResult> AuthorizeSessionAsync(SessionAuthorizationRequest request, CancellationToken cancellationToken = default)Parameters
Section titled “Parameters”request SessionAuthorizationRequest
The session access being authorized.
cancellationToken CancellationToken
The cancellation token.
Returns
Section titled “Returns”ValueTask<RunAuthorizationResult>
The decision.