Zum Inhalt springen
Deutsch

Per-Actor-Policies

Das Object-Storage-Backend kann Store-Level-Defaults für Kompression + Verschlüsselung haben. Aber manchmal brauchen bestimmte Actors andere Einstellungen:

  • Ein sensibler Actor braucht Verschlüsselung (andere nicht).
  • Ein Actor mit großem State profitiert von hohem zstd-Level (andere verwenden gzip).
  • Ein Actor mit kleinem State verzichtet auf Kompression.

Überschreibe pro Actor, indem du die Methoden compression() / encryption() implementierst:

class SensitiveActor extends DurableStateActor<Cmd, State> {
protected encryption() {
return { keyRing: sensitiveKeyRing };
}
protected compression() {
return { algorithm: 'gzip' as const, level: 9 };
}
}

Das Framework ruft diese bei jedem Persist/Load auf und wendet die zurückgegebene Config an.

// Store-Level-Config — gilt für jeden Actor, sofern nicht überschrieben:
const store = new ObjectStorageDurableStateStore({
backend,
compression: { algorithm: 'gzip', level: 6 },
encryption: { keyRing: defaultKeyRing },
});
// Per-Actor: Override
class MyActor extends DurableStateActor<...> {
protected compression() { return { algorithm: 'none' as const }; }
// encryption() nicht überschrieben → verwendet defaultKeyRing
}

Jede Methode ist unabhängig überschreibbar:

  • Eigene Config zurückgeben → diese Config gilt.
  • Nicht überschreiben → Default des Stores gilt.
  • undefined aus der Methode zurückgeben → ebenfalls Default des Stores.
class CreditCardActor extends DurableStateActor<...> {
protected encryption() {
return { keyRing: pciKeyRing }; // separater Key Ring für PCI-Scope
}
}
class GenericActor extends DurableStateActor<...> {
// Kein Override → verwendet Store-Default (keine Verschlüsselung oder generischer keyRing)
}

PCI / HIPAA / GDPR-Scope: als sensibel klassifizierte Daten verwenden einen separaten Master-Key von nicht-sensiblen. Kompromittierung eines keyRings exponiert den anderen nicht.

class ChatTranscriptActor extends DurableStateActor<...> {
// Großer Text-State — hohes zstd-Level gewinnt deutlich
protected compression() {
return { algorithm: 'zstd' as const, level: 19 };
}
}
class CounterActor extends DurableStateActor<...> {
// Winziger State — Kompressions-Overhead übersteigt Einsparungen
protected compression() {
return { algorithm: 'none' as const };
}
}

Passe die Kompression an die Datenform an. Default gzip ist ein sicherer Mittelweg; Per-Actor-Tuning holt mehr raus.

DurableStateActor.persist(state)
serializer.toBinary(state) → JSON- oder CBOR-Bytes
this.compression() → angewendet, wenn nicht 'none'
this.encryption() → angewendet, wenn gesetzt
backend.put(key, ciphertext, opts)

Das Framework schaut bei jedem Persist die Overrides des Actors nach — selbst wenn du die Override-Werte dynamisch änderst (selten), verwenden neue Writes neue Einstellungen.

DurableStateActor.preStart
backend.get(key) → Bytes + Metadaten
Verschlüsselung aus Metadaten erkennen (key-id) → entschlüsseln
Kompression aus Metadaten erkennen (Content-Encoding) → dekomprimieren
serializer.fromBinary → State

Reads verwenden die mit dem Objekt gespeicherten Metadaten, nicht die aktuellen Overrides des Actors. Ein unter pciKeyRing verschlüsseltes Objekt wird über pciKeyRing entschlüsselt, egal ob das aktuelle encryption() des Actors das sagt oder nicht.

Das bedeutet: das Rotieren einer Actor-Policy bricht alte Daten nicht, solange die notwendigen Keys / Algorithmen verfügbar sind.

// Alt: keine Verschlüsselung.
// Neu: Verschlüsselung unter pciKeyRing.
class CreditCardActor extends DurableStateActor<...> {
protected encryption() {
return { keyRing: pciKeyRing };
}
}

Alte (unverschlüsselte) Reads funktionieren — keine Metadaten → Plaintext-Pfad. Neue Writes verschlüsseln. Schließlich:

  • Ein Re-Encryption-Sweep, gefiltert auf die persistenceIds dieses Actors, migriert den Rest.

Siehe Schlüsselrotation.

class Account extends PersistentActor<Cmd, Event, State> {
// Per-Actor-Kompression für Snapshots:
protected compression() {
return { algorithm: 'zstd' as const };
}
// Per-Actor-Verschlüsselung für Snapshots:
protected encryption() {
return { keyRing: accountKeyRing };
}
}

Gleiche Methoden gelten, wenn der Snapshot-Store durch Object Storage gestützt wird. Persistent Actors und Durable State Actors honorieren beide.