How-to
Export and import a policy
Goal
You run the same agent identity in two locations that cannot share storage (different region, different VPC, offline backup, DR site) and want both deployments to apply the same policy. Use the export / import pair instead of swarm mode (which requires shared storage).
How it works
- The source deployment encrypts its policy under its own SKey-derived ASK (derived from a stable seed at deployment time).
ExportEncryptedPolicyAsyncreturns the encrypted blob as-is — no decryption.- You ship the blob and the SKey seed to the destination deployment via any out-of-band channel (signed email, manual copy, key-management system).
- The destination deployment uses the seed to derive the source's SKey ASK locally (same agent identity → same ASK from the same seed), decrypts the blob once, then re-encrypts under its own SKey seed for persistent local storage.
Export on the source
// On the source deployment — capture the encrypted policy blob
string? blob = await client.Authorization.AsCasbin().ExportEncryptedPolicyAsync();
if (blob is null)
{
Console.WriteLine("No policy persisted yet.");
return;
}
// The seed is whatever stable string YOU configured at startup when
// wiring EnableLocalEncryption. Ship it alongside the blob via your
// out-of-band channel.
string seed = MyAppSettings.PolicyStorageSeed;
await File.WriteAllTextAsync("policy-export.he", blob);
File.WriteAllText("policy-seed.txt", seed); Import on the destination
// On the destination deployment — same agent identity, but its own
// per-deployment SKey seed (Local-Seed) configured at startup
string blob = await File.ReadAllTextAsync("policy-export.he");
string sourceSeed = await File.ReadAllTextAsync("policy-seed.txt");
// Build a one-off decrypt func that uses the SOURCE seed to derive the
// source's SKey ASK. Because both deployments share the agent identity,
// this derives the same key the source used to encrypt the blob.
string sourceAsk = await client.FetchInternalKeyAsync(sourceSeed);
Func<string, Task<string>> sourceDecryptFn =
(ciphertext) => client.DecryptMessageUsingSharedKeyAsync(ciphertext, sourceAsk);
// Import — provider decrypts with sourceDecryptFn, parses rules,
// re-encrypts with this deployment's own SKey, persists, reloads.
await client.Authorization.AsCasbin().ImportEncryptedPolicyAsync(blob, sourceDecryptFn); What happens internally
Once the import succeeds, the destination's policy file on disk is encrypted under this deployment's SKey — not the source's. Future reads, writes, and exports from the destination use its own seed. The source seed is used only for the one-off decryption at import time and is not retained.
See also
- The authorization model Concept
- Share a policy across machines (swarm) How-to
- Inspect the loaded policy How-to