Skip to main content
Table of Contents

Interface INamesDataOwner

Namespace
Stratara.Abstractions.Security
Assembly
Stratara.Abstractions.dll

Opt-in declaration on a command that names the tenant, and optionally the user, its fields marked with EncryptDataAttribute belong to.

public interface INamesDataOwner
Extension Methods

Examples

Implement it explicitly from a field the command already carries, so nothing is added to the command's serialized form:

public sealed record TrackPageCommand(
    Guid TenantId,
    [property: EncryptData(DataSensitivityLevel.TenantScoped)] string? Address)
    : ICommand, INamesDataOwner
{
    Guid INamesDataOwner.DataOwnerTenantId => TenantId;
}

Remarks

A command that implements it has its protected fields encrypted for the named owner wherever the framework serializes it — the copy carried to a handler that runs later and the copy the command audit records — whatever session dispatched it. Both copies are written for the same tenant and the same user, and the audit record names that owner as its data owner and the session's actor as its actor. A command that does not implement it is encrypted for the session it was dispatched under.

It is to a command what IAggregateCreationEvent is to a stream's first event: the statement of whose data this is, made by the only party that knows. Use it where the session does not say — a session with no tenant, such as an anonymous endpoint or a saga reacting to a fact one recorded, or a session whose tenant is not the tenant the command's data belongs to.

It authorizes nothing. The session a handler runs under is the dispatching session, unchanged, and nothing compares the named owner against it. Whether the caller may act on that owner's data is decided as for any other command, by the pipeline stages the host registered and by the handler.

The owner is taken as stated. Nothing checks that the named tenant exists, and key material is created for it the first time a field is encrypted for it. Name an owner the code resolved from something it trusts — the stream it loaded, a credential it verified — and never one copied from a request.

An empty DataOwnerTenantId, or an empty DataOwnerUserId, is refused when the command is recorded or dispatched, with an ArgumentException naming the command type. It does not fall back to the session.

A command still waiting when its owner is erased reaches its handler with its protected fields absent, as any record does whose key was destroyed — so give those fields a type that can be absent. A command whose class is marked, and which is therefore encrypted as one unit, cannot be rebuilt at all once its key is gone: it is retried and then kept, and its handler does not run.

Properties

DataOwnerTenantId

The tenant the command's protected fields belong to. Must not be empty.

Guid DataOwnerTenantId { get; }

Property Value

Guid

DataOwnerUserId

The user the command's protected fields belong to, or null when they belong to the tenant alone. Defaults to null. Must not be empty.

Guid? DataOwnerUserId { get; }

Property Value

Guid?