[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:
public class Subscriber
{
[DataSubjectId]
public Guid Id { get; set; }
[PersonalData]
public string Email { get; set; } = "";
}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:
public class PrefixedCustomer
{
[DataSubjectId(Prefix = "cust-")]
public Guid CustomerId { get; set; }
[PersonalData]
public string FullName { get; set; } = "";
}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:
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; } = "";
}In this example:
ClaimantNameis encrypted with the key derived fromClaimantId(group"claimant").WitnessNameis encrypted with the key derived fromWitnessId(group"witness").- Shredding the claimant's key does not affect the witness's data, and vice versa.
Properties Reference
| Property | Type | Default | Description |
|---|---|---|---|
Group | string? | null | Group name for multi-key scenarios. Only [PersonalData] fields in the same group use this subject's key. |
Prefix | string? | null | Prepended 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}| Prefix | Subject ID | Group | Resulting Key ID |
|---|---|---|---|
null | abc-123 | null | abc-123 |
"cust-" | abc-123 | null | cust-abc-123 |
null | abc-123 | "medical" | abc-123:medical |
"cust-" | abc-123 | "medical" | cust-abc-123:medical |
Supported Types
[DataSubjectId] can be applied to:
| Type | Notes |
|---|---|
Guid | Recommended. Globally unique, no collisions. |
string | Useful 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
[PersonalData]-- Marking fields for encryption[DeepPersonalData]-- Nested object encryption- Crypto Engine -- How keys are managed internally
- Attributes Overview -- All four attributes at a glance
