This optional upper-tier path is only for customers who require AWS Nitro or GCP Confidential Space to gate release of the qURL sidecar private key. The standard tunnel install remains the simple default; use this guide after that requirement is confirmed.
Stores private_key.sealed.json instead of durable plaintext key material.
2Cloud attestation
KMS releases only to the approved Nitro or Confidential Space workload.
3Runtime config
OpenNHP plaintext config exists only in the process-lifetime runtime dir.
Outcomes
The advanced tier seals the key and releases it only to the approved workload.
Standard qURL tunnel onboarding does not require this tier. When a customer opts into attested custody, the sidecar still uses the normal first bootstrap or recovery key, but steady state should run from persisted sealed state without keeping QURL_API_KEY or QURL_API_KEY_FILE mounted.
Success criteria
State contains private_key.sealed.json, not durable plaintext private_key.
Replacement instances unseal only when cloud attestation policy matches.
Cloud audit logs show expected KMS operations and no unexpected decrypts.
The tunnel reconnects after removing the bootstrap API key.
Non-goals
It does not replace IAM or KMS policy review.
It does not treat the NHP public key as secret.
It does not make the GCP local token parse a JWT verifier.
It does not make AWS first seal host-compromise-resistant on the parent host.
Architecture model
The optional upper tier makes cloud policy the release boundary.
For this advanced mode, the qURL client fails closed and checks local config, but confidentiality comes from the AWS KMS key policy for Nitro or the GCP Workload Identity Federation and Cloud KMS IAM binding for Confidential Space.
Baseline
file stores durable plaintext key material in the sidecar state directory. Use for development or low-sensitivity local deployments.
Tier 1
aws-kms and gcp-kms store sealed state, but do not add an attested release condition.
Tier 2 (optional advanced)
aws-nitro and gcp-confidential-space tie unseal to cloud attestation and approved workload identity. Use this only when a customer requires attested key release.
Inputs
Collect these before the advanced attestation working session.
Do not start this optional migration until the platform owner and security owner agree on provider, rollout gates, and rollback ownership.
qURL bootstrap
Collect the one-time qURL API key, a stable LAYERV_AGENT_ID, and the persistent state path before first start.
Runtime directory
Use a tmpfs-backed path such as /dev/shm, or set LAYERV_NHP_RUNTIME_DIR. Disk fallback requires explicit LAYERV_ALLOW_DISK_NHP_RUNTIME_DIR opt-in.
Cloud policy
Name the KMS key, steady-state principal, attestation claims, negative-test owner, and audit-log evidence location.
Rollback
For migration, preserve a pre-migration state backup if the customer policy requires rollback to the file provider.
Provider choice
Pick one provider per state volume.
Switching an existing file provider volume to a sealed provider is a one-way migration unless the customer restores a pre-migration backup.
Choose AWS Nitro when
The workload runs in AWS Nitro Enclaves or a NitroTPM-backed attested runtime.
The customer can enforce kms:RecipientAttestation conditions on the KMS key.
An unwrap helper can run inside the attested runtime.
First seal or migration can happen inside the attested runtime or a controlled provisioning window.
Choose GCP Confidential Space when
The workload runs in Google Cloud Confidential Space.
The customer can bind Workload Identity Federation and Cloud KMS IAM to image and service-account claims.
The container can read the Confidential Space attestation token file.
The security owner will validate negative IAM tests before production enablement.
AWS Nitro onboarding
Require KMS Recipient decrypt and reject host plaintext.
aws-nitro uses normal KMS encrypt for first seal, then requires AWS KMS Recipient decrypt on unseal. The client expects CiphertextForRecipient and fails closed if AWS returns host plaintext.
Prerequisites
A customer-managed AWS KMS key in the target region.
A first-seal or migration principal with kms:Encrypt.
A steady-state decrypt principal constrained by Recipient Attestation.
Treat the sample as a KMS key policy, not an IAM identity policy. In a key policy, "Resource": "*" refers to the current key.
IAM principal ARNs intentionally use an empty region segment, for example arn:aws:iam::111122223333:role/qurl-agent-parent, because IAM ARNs are regionless.
Use kms:RecipientAttestation:PCR<PCR_ID> conditions when the customer wants PCR1, PCR2, or custom PCR binding.
The unwrap command is split on whitespace with no shell or quote parsing; stdout must be exactly 32 raw private-key bytes with no trailing newline.
AWS KMS Encrypt has no Recipient mode. Run first seal in the attested runtime whenever possible, or use a controlled provisioning window.
GCP Confidential Space onboarding
Make WIF and Cloud KMS enforce the workload claims.
gcp-confidential-space checks local Confidential Space claims before KMS calls, but the local parse is not a JWT verifier. WIF/IAM plus Cloud KMS are the real cryptographic release boundary.
Mandatory warning
If the customer does not enforce the same image digest and service account in WIF/IAM, local token claims can pass startup while Cloud KMS still releases the key. Treat the negative IAM test as a production gate.
The ${APPROVED_IMAGE_DIGEST} placeholders are shell variables set at the top of the snippet; keep them literal when copying the block.
GCP implementation rules
The default token path is /run/container_launcher/attestation_verifier_claims_token.
Local checks require swname=CONFIDENTIAL_SPACE, dbgstat=disabled-since-boot, and STABLE support attributes.
Image digest and service account pins must match the customer's WIF attribute mapping and Cloud KMS IAM binding.
Run a negative test with the wrong image or service account before production.
Bootstrap and migration
Seal only after verify-unseal succeeds.
The sidecar writes sealed state only after it proves the selected provider can unseal it. If verification fails, the client exits rather than writing an unusable sealed blob.
New deployment
Mount the qURL API key as a file and set QURL_API_KEY_FILE.
Set a stable LAYERV_AGENT_ID.
Set the provider-specific environment variables.
Start the agent and wait for seal, verify, and tunnel connection.
Restart without the API key and confirm reconnect from sealed state.
File-provider migration
Back up the state volume if rollback policy requires it.
Set LAYERV_KEY_PROVIDER to the sealed provider.
Set LAYERV_ALLOW_KEY_MIGRATION=true for one restart only.
Confirm private_key.sealed.json exists.
Remove the migration acknowledgement and restart again.
Validation plan
Capture evidence before production handoff.
The customer change ticket should include startup state, tunnel restart behavior, negative cloud policy tests, and cloud audit evidence.
Startup and state
Agent starts with the selected provider and fails when required provider env is missing.
State contains agent_id and private_key.sealed.json.
Durable plaintext private_key is absent after successful migration.
Runtime OpenNHP config is materialized only in the runtime directory.
Tunnel behavior
Agent registers or loads the expected LAYERV_AGENT_ID.
Routes connect through the qURL tunnel and survive an agent restart.
Restart without QURL_API_KEY or QURL_API_KEY_FILE succeeds from sealed state.
Removing attestation inputs causes startup failure before tunnel connection.
Cloud policy gates
AWS: approved attestation decrypt returns CiphertextForRecipient, not host plaintext.
AWS: unapproved image digest or PCR cannot decrypt.
GCP: approved Confidential Space workload obtains KMS access.
GCP: non-attested principal, wrong image digest, or wrong service account cannot decrypt.
Useful local checks
These examples use the default state directory. If the deployment sets LAYERV_AGENT_STATE_DIR, replace /var/lib/layerv/agent with that path.
Local validation
# Confirm sealed state
ls -la /var/lib/layerv/agent
test -f /var/lib/layerv/agent/private_key.sealed.json
test ! -f /var/lib/layerv/agent/private_key
# Confirm the provider recorded in the sealed blob
grep -m1 -E '"provider"[[:space:]]*:[[:space:]]*"(aws-nitro|gcp-confidential-space)"' \
/var/lib/layerv/agent/private_key.sealed.json
# Confirm steady-state restart does not need the API key
# Remove QURL_API_KEY / QURL_API_KEY_FILE from compose or service env first.
docker compose up -d --force-recreate qurl-agent
Operations handoff
Leave the customer with ownership, evidence, and rollback notes.
After onboarding, the customer operations owner should know when an API key is needed, what state to preserve, how attestation failures surface, and which audit logs matter.
Keep the qURL API key available only for first bootstrap or state recovery.
Do not delete or share the state volume; it contains the stable agent identity and sealed key blob.
Coordinate KMS key policy changes with qURL restarts.
Review CloudTrail or Cloud Audit Logs for unexpected decrypt attempts.
Acceptance checklist
Security owner approved cloud KMS policy and negative tests.
Platform owner confirmed restart behavior without the API key.
Operations owner accepted troubleshooting and rollback notes.
LayerV owner confirmed qURL tunnel connectivity and expected agent ID.
Troubleshooting
Common attested-provider failures.
Most failures are missing provider env vars, stale attestation inputs, cloud policy mismatch, or state volume drift.
Startup says a provider env var is missing.
Set the provider-specific env vars in this guide. For GCP, image digest and service account are required before the token file is read.
AWS unwrap helper fails or returns the wrong size.
Verify the helper runs in the attested runtime and writes exactly 32 raw private-key bytes to stdout with no trailing newline.
AWS KMS returns host plaintext.
Fix the key policy or attestation document. aws-nitro intentionally rejects host plaintext and requires CiphertextForRecipient.
GCP local checks pass, but KMS decrypt fails.
Compare local pins to WIF attribute mapping and Cloud KMS IAM binding. The federated principal must match the approved workload.
Agent asks for an API key after restart.
Restore the correct state directory or intentionally re-bootstrap. The API key is only for first bootstrap or state recovery.
Related docs
Use this with the sidecar install guide.
Start with the standard tunnel install guide, then use this optional advanced companion only when the customer needs attested key custody.