Problem
A snapshot captures execution state at a point in time. Any authorization derived
from outside the actor can change while it is checkpointed. On restore there is
no point at which an external component can reconcile the two.
Concretely, on the full-scope restore path:
- no container is created, so no OCI hook fires (
restore.go calls neither
CreateContainer nor StartContainer; only run.go does)
- the guest resumes with whatever in-guest state the snapshot captured
- the actor becomes reachable with no opportunity to re-validate it
So a policy decision made while the actor slept cannot be applied to it. The
actor comes back with the authority it had when the snapshot was taken.
This is not specific to any one policy system. Anything that establishes state
before a workload runs and needs it to still be valid afterwards has the same
problem: capability tokens, short-lived credentials, admission decisions, lease
or quota state, tenancy or residency constraints.
What already exists
The lifecycle point is arguably already there. restoreFullScope blocks before
returning:
// Block until every readyz-enabled container reports 200.
if err := readyz.WaitAll(ctx, containers, ateomnet.ActorVethIP); err != nil {
and durable volumes are re-materialised even earlier, before the VM starts:
// Restore the durable-dir volumes before anything can observe them
if hasDurableVolumes(p.containers) {
if err := untarDurableVolumes(durableDir, restoreDir); err != nil {
So restore already has a stage where the actor is not yet reachable. What is
missing is a way for anything to run there.
Suggested shape
An optional, configured reconciliation step invoked on the restore path before
the actor becomes reachable, which can fail the restore. Roughly:
- runs after durable volumes are re-materialised and before the VM is resumed, so
a rejected actor never executes rather than being stopped mid-flight
- receives enough identity to make a decision: actor ref and uid, template, and
the restored durable directory
- a non-nil error fails the restore, and the existing teardown path already
handles cleanup
- absent configuration means no behavioural change
Placing it before the VM resumes matters more than the exact interface. Doing it
after readyz means the workload has already run.
Why we are raising it
We are building kernel-level enforcement that binds a workload to an authority
epoch established before it runs, and we need that epoch re-checked when a
snapshot is restored so a revoked authority cannot come back with the snapshot.
We have this working locally by reading state the guest wrote onto the durable
share and comparing it at the untar point, which is enough for a demonstration
but relies on an implementation detail rather than a contract.
Happy to send a PR for whichever shape you prefer, or to adapt to something you
already have planned. Related: #1224 (guest_hook_path propagation), which is
the corresponding gap on the pre-activation side.
Problem
A snapshot captures execution state at a point in time. Any authorization derived
from outside the actor can change while it is checkpointed. On restore there is
no point at which an external component can reconcile the two.
Concretely, on the full-scope restore path:
restore.gocalls neitherCreateContainernorStartContainer; onlyrun.godoes)So a policy decision made while the actor slept cannot be applied to it. The
actor comes back with the authority it had when the snapshot was taken.
This is not specific to any one policy system. Anything that establishes state
before a workload runs and needs it to still be valid afterwards has the same
problem: capability tokens, short-lived credentials, admission decisions, lease
or quota state, tenancy or residency constraints.
What already exists
The lifecycle point is arguably already there.
restoreFullScopeblocks beforereturning:
and durable volumes are re-materialised even earlier, before the VM starts:
So restore already has a stage where the actor is not yet reachable. What is
missing is a way for anything to run there.
Suggested shape
An optional, configured reconciliation step invoked on the restore path before
the actor becomes reachable, which can fail the restore. Roughly:
a rejected actor never executes rather than being stopped mid-flight
the restored durable directory
handles cleanup
Placing it before the VM resumes matters more than the exact interface. Doing it
after readyz means the workload has already run.
Why we are raising it
We are building kernel-level enforcement that binds a workload to an authority
epoch established before it runs, and we need that epoch re-checked when a
snapshot is restored so a revoked authority cannot come back with the snapshot.
We have this working locally by reading state the guest wrote onto the durable
share and comparing it at the untar point, which is enough for a demonstration
but relies on an implementation detail rather than a contract.
Happy to send a PR for whichever shape you prefer, or to adapt to something you
already have planned. Related: #1224 (
guest_hook_pathpropagation), which isthe corresponding gap on the pre-activation side.