Skip to content

[DataSubjectId]

The [DataSubjectId] attribute identifies the property that holds the data subject identifier -- the person whose personal data this entity contains. Tayra uses this value to derive the encryption key ID in the key store.

Basic Usage

Apply [DataSubjectId] to a Guid or string property:

cs
public class Subscriber
{
    [DataSubjectId]
    public Guid Id { get; set; }

    [PersonalData]
    public string Email { get; set; } = "";
}
anchor

The encryption key for this entity will be stored under the key ID equal to Id.ToString() (e.g., "a1b2c3d4-e5f6-7890-abcd-ef1234567890").

Key ID Prefix

The Prefix property prepends a string to the key ID, which is useful for namespacing keys by entity type:

cs
public class PrefixedCustomer
{
    [DataSubjectId(Prefix = "cust-")]
    public Guid CustomerId { get; set; }

    [PersonalData]
    public string FullName { get; set; } = "";
}
anchor

With Prefix = "cust-", the key ID becomes "cust-a1b2c3d4-e5f6-7890-abcd-ef1234567890". This prevents key ID collisions when different entity types share the same subject identifier.

Prefix Conventions

Use short, descriptive prefixes with a trailing delimiter:

  • "cust-" for customers
  • "patient-" for patients
  • "emp-" for employees

The prefix is included in the key store, so it affects crypto-shredding: DeleteKeyAsync("cust-{id}") only deletes the customer key, not keys for the same person in other contexts.

Multiple Groups

A single entity can have multiple [DataSubjectId] attributes for different groups. Each group uses its own encryption key:

cs
public class InsuranceClaim
{
    [DataSubjectId(Group = "claimant")]
    public Guid ClaimantId { get; set; }

    [DataSubjectId(Group = "witness")]
    public Guid WitnessId { get; set; }

    [PersonalData(Group = "claimant")]
    public string ClaimantName { get; set; } = "";

    [PersonalData(Group = "witness")]
    public string WitnessName { get; set; } = "";
}
anchor

In this example:

  • ClaimantName is encrypted with the key derived from ClaimantId (group "claimant").
  • WitnessName is encrypted with the key derived from WitnessId (group "witness").
  • Shredding the claimant's key does not affect the witness's data, and vice versa.

Properties Reference

PropertyTypeDefaultDescription
Groupstring?nullGroup name for multi-key scenarios. Only [PersonalData] fields in the same group use this subject's key.
Prefixstring?nullPrepended to the key ID in the key store. Useful for namespacing by entity type.

Key ID Derivation

The encryption key ID is built from three components:

{Prefix}{SubjectId.ToString()}{:Group}
PrefixSubject IDGroupResulting Key ID
nullabc-123nullabc-123
"cust-"abc-123nullcust-abc-123
nullabc-123"medical"abc-123:medical
"cust-"abc-123"medical"cust-abc-123:medical

Supported Types

[DataSubjectId] can be applied to:

TypeNotes
GuidRecommended. Globally unique, no collisions.
stringUseful when your identifier is a natural key (e.g., email, external ID).

The Roslyn analyzer rule TAYRA002 will warn if [DataSubjectId] is applied to an unsupported type (e.g., int, DateTime).

Null Subject IDs

If the [DataSubjectId] property value is null at encryption time, Tayra skips encryption for all fields in that group. Ensure subject IDs are always populated before calling EncryptAsync.

See Also