What identity continuity invariants must survive when an agent's host is migrated between cloud regions?

**Date of Record:** 2026 October 27 **Scope:** Applies when an agentic session's host (VM, container, or bare-metal instance) is migrated between cloud regions or availability zones, and the agent's identity (IP-bound tokens, region-scoped certificates, or locality-based permissions) may become invalid or be treated differently by downstream consumers. Does not apply to sessions with strictly portable identity (SPIFFE, cloud-agnostic tokens) or sessions that complete before migration.

Core Distinction

The separation between **identity validity** (the credentials are still cryptographically valid) and **identity locational continuity** (downstream consumers accept the credentials as coming from the same principal, not a suspicious new location). Relying on validity alone creates the **Migration Identity Suspicion**: the agent's tokens are valid, but downstream fraud detection sees the new region as anomalous and rejects the request, breaking the session.

What Was Observed

In cloud-migrated agent architectures, failing to preserve identity continuity produces three primary failure modes:

  1. **Region-Scoped Token Rejection:** Tokens issued for `us-east-1` are rejected when presented from `eu-west-1`, even though the token hasn't expired.
  2. **Behavioral Anomaly Detection:** Downstream systems flag the agent as compromised because its IP geolocation changed drastically between calls, triggering rate limits or account locks.
  3. **Permission Scope Change:** The migration moves the agent to a region where its permissions are interpreted differently (e.g., GDPR-scoped data requires EU-only processing).

Recorded Elements

  1. **`migration_continuity_receipt`:** A cryptographic proof that the migration was authorized by the principal, establishing that the new region is legitimate.
  2. **`region_attestation_bundle`:** The full chain of region attestations (original region, migration path, destination region), allowing downstream consumers to verify the migration was legitimate.
  3. **`permission_scope_hash_at_migration`:** The cryptographic hash of the agent's permission scope before migration, allowing downstream consumers to verify no scope changes occurred.
  4. **`behavioral_continuity_signature`:** The cryptographic proof that the agent's behavior before and after migration matches (e.g., same request patterns, same data access patterns).

Condition of Validity

* **Applies when:** The agent's identity is region-scoped or locality-sensitive, migrations are possible during a session, and downstream consumers include anomaly detection that could flag migrations. * **Does not apply when:** The agent's identity is region-agnostic (SPIFFE, cloud-neutral tokens), or the migration happens only between sessions (not mid-session).

Decision Boundary

  1. **Did a migration occur mid-session?** If no, standard identity verification applies. If yes, proceed.
  2. **Is a `migration_continuity_receipt` present, signed by the principal?** If no, the migration appears unauthorized. The agent must re-authenticate or the migration must be flagged.
  3. **Does the `permission_scope_hash_at_migration` match the current scope?** If no, the scope changed during migration. The agent must re-verify permissions.
  4. **Conversely, when can downstream consumers accept the migrated identity without continuity proof?** Only when the agent's identity is region-agnostic (so migration has no identity impact) or downstream anomaly detection explicitly tolerates region migrations (e.g., explicit migration window in fraud detection).

Operational Effect

  1. **Migration Acceptance:** Enables downstream consumers to accept the migrated agent without triggering fraud alerts.
  2. **Scope Preservation:** Verifies the migration didn't silently expand or restrict the agent's permissions.
  3. **Behavioral Continuity:** Provides cryptographic proof that the agent's behavior matches pre-migration, closing the anomaly detection gap.
from dataclasses import dataclass
from enum import Enum, auto
import hashlib
import json

class ContinuityVerdict(Enum):
    NO_MIGRATION = auto()
    CONTINUITY_VERIFIED = auto()
    MIGRATION_UNAUTHORIZED = auto()
    SCOPE_CHANGED = auto()

@dataclass(frozen=True)
class MigrationState:
    original_region: str
    current_region: str
    migration_continuity_receipt: str | None
    permission_scope_hash_at_migration: str
    current_permission_scope_hash: str

@dataclass(frozen=True)
class ContinuityPolicy:
    region_scoped_identity: bool
    require_scope_preservation: bool

@dataclass(frozen=True)
class ContinuityManifest:
    verdict: ContinuityVerdict
    directive: str
    manifest_digest: str

class MigrationIdentityGuard:
    @staticmethod
    def _hash(data: str) -> str:
        return hashlib.sha256(data.encode("utf-8")).hexdigest()

    @classmethod
    def evaluate_migration(
        cls, state: MigrationState, policy: ContinuityPolicy
    ) -> ContinuityManifest:
        
        # Gate 1: No migration
        if state.original_region == state.current_region:
            digest = cls._hash(json.dumps({
                "region": state.current_region
            }, sort_keys=True))
            return ContinuityManifest(
                verdict=ContinuityVerdict.NO_MIGRATION,
                directive="PROCEED: No migration detected.",
                manifest_digest=digest
            )

        # Gate 2: Non-region-scoped identity
        if not policy.region_scoped_identity:
            digest = cls._hash(json.dumps({
                "from": state.original_region,
                "to": state.current_region,
                "identity": "PORTABLE"
            }, sort_keys=True))
            return ContinuityManifest(
                verdict=ContinuityVerdict.CONTINUITY_VERIFIED,
                directive="PROCEED: Identity is region-agnostic. Migration irrelevant.",
                manifest_digest=digest
            )

        # Gate 3: Migration authorization
        if not state.migration_continuity_receipt:
            return ContinuityManifest(
                verdict=ContinuityVerdict.MIGRATION_UNAUTHORIZED,
                directive=f"HALT: Migration {state.original_region} -> {state.current_region} lacks continuity receipt.",
                manifest_digest=cls._hash(f"UNAUTHORIZED:{state.current_region}")
            )

        # Gate 4: Scope preservation
        if policy.require_scope_preservation:
            if state.permission_scope_hash_at_migration != state.current_permission_scope_hash:
                return ContinuityManifest(
                    verdict=ContinuityVerdict.SCOPE_CHANGED,
                    directive="HALT: Permission scope changed during migration.",
                    manifest_digest=cls._hash(f"SCOPE_CHANGE:{state.current_region}")
                )

        # Gate 5: Verified
        digest = cls._hash(json.dumps({
            "from": state.original_region,
            "to": state.current_region,
            "receipt": state.migration_continuity_receipt,
            "scope": state.permission_scope_hash_at_migration
        }, sort_keys=True))
        
        return ContinuityManifest(
            verdict=ContinuityVerdict.CONTINUITY_VERIFIED,
            directive="PROCEED: Migration authorized, scope preserved, identity continuous.",
            manifest_digest=digest
        )