Scrydon
Security

Isolation Policy Operations

Create, inspect, change, revoke, and verify an organization's untrusted-execution isolation policy without allowing workflow authors to weaken it.

platform.isolation_policy is the organization-owned strengthening layer for untrusted-step isolation. Only an organization owner or admin can write it. Workflow, integration, and service-account callers cannot select a tier or widen the policy.

Policy shape

type IsolationPolicy = {
  isolateUntrusted?: boolean
  requireTrueVm?: boolean
  fallback?: 'hardened' | 'hard_refuse'
}

Every field is optional. A missing field inherits the deployment value. Explicit false or a weaker fallback can never reduce the deployment's immutable floor. The schema is strict: unknown fields, invalid fallback names, and non-boolean flags are rejected. mediated is not accepted as organization policy in this release because the native egress enforcer cannot run under gVisor. The runtime-plane wire remains backward-readable, while legacy deployment values fail closed to hard_refuse.

Create or update

Use the authenticated Better Auth client from an owner/admin session. The same upsert operation creates the record on first use and updates it thereafter:

const result = await authClient.organization.policy.update({
  organizationId,
  key: 'platform.isolation_policy',
  value: {
    isolateUntrusted: true,
    requireTrueVm: true,
    fallback: 'hard_refuse',
  },
})

if (result.error) throw result.error

Writes are intentionally session-only. There is no service-to-service write endpoint, API key mutation path, or workflow mutation capability. This prevents an execution service from changing the control that governs its own sandbox.

Inspect the active organization override

const result = await authClient.organization.policy.get({
  organizationId,
  key: 'platform.isolation_policy',
})

if (result.error) throw result.error
console.log(result.data?.value ?? {})
console.log(result.data?.lastModifiedBy, result.data?.updatedAt)

get returns the stored override, not a computed effective-policy document. Treat lastModifiedBy and updatedAt as change metadata. A post-write hook attempts isolation.policy.updated with the previous and next values. The policy write can succeed if audit delivery fails, so operators must confirm the matching event after every change and alert on hook failures.

Revoke the organization override

There is no public delete operation. Revoke every organization override by writing the empty strict policy:

await authClient.organization.policy.update({
  organizationId,
  key: 'platform.isolation_policy',
  value: {},
})

This keeps an auditable row while making all three fields inherit deployment values. Do not delete the database record directly: that bypasses authorization and the isolation.policy.updated lifecycle event.

Change procedure

  1. Record the current row, deployment defaults, target cluster, and change ticket.
  2. Confirm the runtime plane reports the required RuntimeClass and a Ready, schedulable node. Capability discovery is not workload proof.
  3. Write the policy from an owner/admin session and retain the returned lastModifiedBy and updatedAt.
  4. Run a non-production canary containing each affected unsafe surface. A true-VM canary must report microvm, kata-vm-isolation, a fresh workload/pod identity, and candidate image evidence in its trace.
  5. Test the negative case by making the required tier unavailable. A requireTrueVm: true or fallback: 'hard_refuse' policy must refuse; it must never produce a weaker successful trace.
  6. Roll back by restoring the captured value, or write {} to return to deployment inheritance.

No dry-run API exists in this release. Reading the stored row and runtime-plane capabilities can predict the decision, but only a candidate-image canary proves scheduling, admission, guest boot, governed egress, and teardown. Do not represent a capability response as execution attestation.

Deployment baseline and IaC

Deployment defaults are configured as immutable release inputs in Helm/GitOps:

  • RUNTIME_PLANE_ISOLATE_UNTRUSTED
  • RUNTIME_PLANE_EXEC_REQUIRE_TRUE_VM
  • RUNTIME_PLANE_EXEC_FALLBACK (defaults to hard_refuse)

Commit and review those values as normal deployment IaC. They are a server-enforced immutable minimum: boolean requirements combine with logical OR, and fallback resolution selects the stricter supported value (hard_refuse > hardened). An organization admin may strengthen the boundary but cannot weaken it.

The write endpoint requires a user session, so unattended Terraform/GitOps reconciliation of organization rows is also not supported. Do not automate it with stored browser cookies or direct database writes. Use GitOps for deployment defaults and an authorized admin change for organization overrides.

Scope and binding limits

The policy is organization-scoped. It does not support workspace or workspace-environment bindings, scheduled activation, approval workflows, or per-block exceptions. Unknown binding fields are rejected by the strict schema. Deployments that require different isolation postures per workspace must use separate organizations/deployments until a first-class, authorization-reviewed binding contract ships.

For the tier decision matrix and deployment support, see Untrusted Step Isolation.

On this page

On this page