---
title: Subject
---

The `Subject` is Chronicle's compliance identity — the value used to key per-subject material such as PII encryption keys. When you append an event that contains `[PII]`-annotated properties, Chronicle encrypts those properties under the subject's key. Selecting the correct subject on the command ensures that events land under the right encryption key so they can be decrypted later.

When no explicit subject is supplied, Chronicle defaults to the `EventSourceId`. Setting a subject on the command is only necessary when the compliance identity differs from the aggregate identity — for example, when a command mutates an _order_ aggregate but the PII belongs to the _customer_.

## Resolution Order

Arc resolves the subject from the command in this order:

1. **Return a `Subject`** from `Handle()` as part of the response tuple.
2. **Implement `ICanProvideSubject`** on the command record and return the subject from `GetSubject()`.
3. **Add a property of type `Subject`** to the command.
4. **Decorate a property with `[Subject]`** from `Cratis.Chronicle` — Arc reads its value and converts it to a `Subject`.

If none of these are present, no subject is passed to Chronicle and it falls back to using the `EventSourceId`.

## Returning Subject from Handle

The simplest approach when the subject is computed inside the handler:

```csharp
using Cratis.Arc.Commands;
using Cratis.Chronicle;
using Cratis.Chronicle.Events;

[Command]
public record PlaceOrder(EventSourceId OrderId, CustomerId CustomerId, decimal Amount)
{
    public (OrderPlaced, Subject) Handle() =>
        (new OrderPlaced(OrderId, CustomerId, Amount), new Subject(CustomerId.Value.ToString()));
}

[EventType]
public record OrderPlaced(EventSourceId OrderId, CustomerId CustomerId, decimal Amount);
```

Arc detects the `Subject` in the tuple response and passes it to `Append` automatically. The `Subject` is treated as append metadata, so it does not become the command response even when you also return another response value in the same tuple.

## ICanProvideSubject Interface

Use `ICanProvideSubject` when the subject is derived from command properties and you want an explicit, discoverable contract:

```csharp
using Cratis.Arc.Commands;
using Cratis.Arc.Chronicle.Commands;
using Cratis.Chronicle;
using Cratis.Chronicle.Events;

[Command]
public record PlaceOrder(EventSourceId OrderId, CustomerId CustomerId, decimal Amount)
    : ICanProvideSubject
{
    public Subject GetSubject() => new(CustomerId.Value.ToString());

    public OrderPlaced Handle() => new(OrderId, CustomerId, Amount);
}
```

## [Subject] Attribute on a Property

When a command property directly represents the compliance identity, mark it with `[Subject]` from `Cratis.Chronicle`. Arc reads the property value and converts it to a `Subject`:

```csharp
using Cratis.Arc.Commands;
using Cratis.Chronicle;
using Cratis.Chronicle.Events;

[Command]
public record PlaceOrder(EventSourceId OrderId, [Subject] CustomerId CustomerId, decimal Amount)
{
    public OrderPlaced Handle() => new(OrderId, CustomerId, Amount);
}
```

If the property is already of type `Subject`, Arc uses it directly even without `[Subject]`. Any other `[Subject]`-annotated type is converted via its `ToString()` representation.

## Relationship to PII Decryption

Chronicle uses the subject as the lookup key for PII encryption keys. When a read model contains `[PII]`-annotated properties, Arc uses the same subject in two places:

- query responses, where Arc's [PII](/arc/backend/chronicle/compliance/pii/) interceptor calls `Release()` before the read model is served to the client
- command-side read model dependencies, where Arc resolves the subject from the current command context and releases the injected read model before your handler or validator uses it

The subject set here at append time must therefore match the subject used on the read model's `[Subject]`-marked property.
