A bootstrap key is minted
Whichever setup method you use, LayerV creates or finds the connector for your resource name and mints a one-hour bootstrap key for first registration.
Connector setup guide
Install a lightweight connector beside an existing app or API. Approved people, applications, and agents can reach it through LayerV while the resource stays off the public internet.
Works with Docker, Docker Compose, ECS/Fargate, and Kubernetes.
Quick start
Tell LayerV what you are connecting and where it runs. We’ll give you the setup for your environment.
Give this to your coding agent
Install a LayerV Connector beside my existing service.
Resource name: prod-dashboard
Local port: 8080
Runtime: Docker
Keep the service off the public internet. Preserve the connector state across restarts and remove the temporary bootstrap credential after the connector successfully connects.
Before making changes, inspect the current environment and explain what you will update.Use cases
Connect the resource once, then bring approved access into the applications, agents, developer tools, and integrations your team already uses.
Let Claude, Cursor, or another approved agent work with an internal service without exposing it publicly or handing over permanent infrastructure credentials.
Make an admin panel, operations dashboard, or support tool available only after LayerV verifies the request.
Give a teammate, contractor, or customer access without publishing the environment or creating another public login page.
Use LayerV's APIs and SDKs to bring protected access into your own application, command-line workflow, or supported integration.
How it works
The connector runs beside your service and establishes an outbound connection to LayerV. When a person, application, or agent requests access, LayerV verifies the request before making the resource reachable.
Connector identity
Used to register the connector during its first successful start.
Remove it after the connector connects.
Stores the connector identity used during future restarts.
Keep it available and do not share one state directory between concurrently running connectors.
Delete the key. Keep the state.
Learn about connector identity and recoveryGo deeper
Start with the generated setup. Reach for the deeper guides when you are deploying, scaling, or operating connectors in production.
Docker, Docker Compose, ECS/Fargate, and Kubernetes.
Registration, persistent state, rotation, and recovery.
Secret handling, network behavior, and safe deployment practices.
Runtime logs, structured audit records, and log shipping.
AWS KMS, Google Cloud KMS, and attested key providers.
Installation, configuration, permissions, and recovery failures.
Mental model
The bootstrap key is deliberately temporary. The durable connector identity lives in the mounted agent-state directory after the first successful start.
Whichever setup method you use, LayerV creates or finds the connector for your resource name and mints a one-hour bootstrap key for first registration.
On first start, the connector uses the bootstrap key to register its persistent NHP keypair and cache its identity under the agent-state directory.
After the first successful connection, remove the bootstrap key. Future restarts use the mounted state directory and fail closed if that state is missing.
The YAML only names local routes. The connector knocks through NHP and receives the public address at runtime; customers do not configure internal LayerV hosts.
Concepts
These are the names that show up in setup, Docker, and the dashboard. Once these are clear, the install flow becomes straightforward.
The stable identifier for one connector inside your account, such as prod-dashboard. The runtime sets it via the QURL_CONNECTOR_ID environment variable. Use the same ID for replicas of the same service. Do not reuse an ID for a different service.
The short handle used to request access later, such as $prod. If you leave it blank, LayerV uses the ID. The alias can change; the ID should not.
A short-lived key used to register the connector on first start or after state recovery. It is not steady-state connector auth. Remove it after the first successful connection.
The persistent volume that stores the connector identity, agent_id, NHP peer config, and identity cache. The default file provider stores plaintext key material; KMS providers store a sealed blob. Treat backups as secret-bearing.
The qurl-proxy.yaml file tells the connector which local service to expose. Connector identity comes from QURL_CONNECTOR_ID, so the generated route file intentionally omits name and server.addr; placement comes from bootstrap and the NHP ACK.
The deployment target, such as Docker, Compose, ECS/Fargate, or Kubernetes. It controls how the connector reaches localhost and where durable agent state lives.
Runtime guides
The setup panel above tailors the generated block from this choice. The runtime decides how 127.0.0.1 reaches your local service and where persistent agent state lives.
A web app already running in one Docker container on a Linux host.
/qurl-admin protect-connector prod-dashboard env:docker port:8080 container:webAn app already described by compose.yaml.
/qurl-admin protect-connector prod-dashboard env:docker-compose port:8080 service:webA task with awsvpc networking and durable storage for connector state.
/qurl-admin protect-connector prod-dashboard env:ecs-fargate port:8080A same-Pod sidecar in GKE, EKS, or another Kubernetes cluster.
/qurl-admin protect-connector prod-dashboard env:kubernetes port:8080Docker details
You should normally use the personalized generated block from the setup panel. This abbreviated version shows the durable contract so it is clear why each mount and environment variable exists.
# The generated block is personalized for your connector ID and image.
# Replace vX.Y.Z with the immutable image tag shown in your setup output.
# This is the important shape it follows.
QURL_CONNECTOR_ID='prod-dashboard'
WEB_CONTAINER='web'
CONNECTOR_CONTAINER="qurl-connector-${QURL_CONNECTOR_ID}"
SECRET_DIR="/run/secrets/qurl-connector/${QURL_CONNECTOR_ID}"
AGENT_STATE_DIR="/var/lib/layerv/qurl-connector/${QURL_CONNECTOR_ID}/agent"
CONFIG_FILE="$PWD/qurl-proxy-${QURL_CONNECTOR_ID}.yaml"
# The block prompts for the bootstrap key with hidden input.
# Do not paste the key into the shell script itself.
docker run -d \
--name "$CONNECTOR_CONTAINER" \
--network "container:${WEB_CONTAINER}" \
--restart=on-failure:5 \
-v "$AGENT_STATE_DIR:/var/lib/layerv/agent" \
-v "$SECRET_DIR:$SECRET_DIR:ro" \
-v "$CONFIG_FILE:/work/qurl-proxy.yaml:ro" \
-e QURL_API_KEY_FILE="$SECRET_DIR/api_key" \
-e QURL_CONNECTOR_ID="$QURL_CONNECTOR_ID" \
ghcr.io/layervai/qurl-connector:vX.Y.ZSecurity posture
The bootstrap key is needed for first registration and explicit state recovery. It is not the long-lived connector credential. The long-lived identity is the keypair under the mounted agent-state directory.
Standard qURL mode does not put LayerV internal routing addresses in customer YAML. The connector bootstraps, knocks, receives the public FRP host and port in the NHP ACK, and dials that address at runtime.
Do not paste the bootstrap key into a saved shell script. Paste it only when the generated block prompts, or put it in the runtime secret manager.
Do not delete the agent-state directory, volume, or PVC after first start. It stores the connector identity used for future restarts.
Do not share one agent-state volume across concurrently running connectors. Replicas can share an ID, but each replica needs its own state.
Do not put connect.layerv, proxy.layerv, frps-*.internal, server.addr, or a public connection port in qurl-proxy.yaml for standard connector installs.
prod-dashboard reaches the service.Observability
The connector emits a structured audit record for each bootstrap, knock, login, proxy, and teardown decision. Audit logging is on by default and mirrored into your runtime logs; route it to a compliance-grade JSONL file when you need forensic-grade retention.
The dedicated guide covers the event taxonomy, the JSONL schema, sink topologies, the filter-by-outcome rule for central log shippers, and rotation and retention defaults.
audit:
enabled: true
file_path: /var/log/layerv/qurl-connector/audit.log
mirror_slog: true # also mirrored into your runtime logs at INFOAdvanced key storage
The default file provider is the simplest install: it stores the connector private key in the mounted agent-state directory with mode 0600. Enterprise host-mode installs can choose aws-kms or gcp-kms so durable state contains private_key.sealed.json instead of plaintext key files.
Startup decrypts the sealed blob with cloud KMS, writes the plaintext runtime config required by OpenNHP under tmpfs, and removes that runtime directory on clean shutdown. Warm restarts need live KMS decrypt permission, so KMS and IAM reachability become part of the connector startup SLO.
# AWS KMS
-e LAYERV_KEY_PROVIDER=aws-kms \
-e LAYERV_AWS_KMS_KEY_ID=arn:aws:kms:us-east-1:111122223333:key/1234abcd-... \
-e LAYERV_AWS_KMS_REGION=us-east-1
# GCP Cloud KMS
-e LAYERV_KEY_PROVIDER=gcp-kms \
-e LAYERV_GCP_KMS_KEY_NAME=projects/acme-prod/locations/us/keyRings/qurl/cryptoKeys/agent-identity
# Optional sealed-provider runtime placement. Use tmpfs.
-e LAYERV_NHP_RUNTIME_DIR=/dev/shm
# Existing file-provider volume migration, one restart only:
-e LAYERV_ALLOW_KEY_MIGRATION=true/dev/shm available, or set LAYERV_NHP_RUNTIME_DIR to another tmpfs-backed path. Do not use disk-backed runtime dirs in production.LAYERV_ALLOW_KEY_MIGRATION=true for the migration restart only, then remove it after private_key.sealed.json is written.aws-nitro or gcp-confidential-space.Standard connector onboarding stays simple. AWS Nitro and GCP Confidential Space are an optional upper tier for customers whose security owner requires cloud attestation before KMS releases the connector private key.
# AWS Nitro attested KMS release
-e LAYERV_KEY_PROVIDER=aws-nitro \
-e LAYERV_AWS_KMS_KEY_ID=arn:aws:kms:us-east-1:111122223333:key/... \
-e LAYERV_AWS_KMS_REGION=us-east-1 \
-e LAYERV_AWS_NITRO_ATTESTATION_DOCUMENT_FILE=/run/qurl/attestation.cose \
-e LAYERV_AWS_NITRO_ATTESTATION_DOCUMENT_ENCODING=raw \
-e LAYERV_AWS_NITRO_RECIPIENT_UNWRAP_COMMAND=/opt/qurl/bin/unwrap-recipient
# GCP Confidential Space attested KMS release
-e LAYERV_KEY_PROVIDER=gcp-confidential-space \
-e LAYERV_GCP_KMS_KEY_NAME=projects/acme-prod/locations/us/keyRings/qurl/cryptoKeys/agent-identity \
-e LAYERV_GCP_CONFIDENTIAL_SPACE_TOKEN_FILE=/run/container_launcher/attestation_verifier_claims_token \
-e LAYERV_GCP_CONFIDENTIAL_SPACE_IMAGE_DIGEST=sha256:... \
-e LAYERV_GCP_CONFIDENTIAL_SPACE_SERVICE_ACCOUNT=qurl-agent@acme-prod.iam.gserviceaccount.comTroubleshooting
Most failures are local setup issues: missing Docker names, missing config files, wrong directory ownership, or state/key mismatch after recovery.
Replace the placeholder with the Docker container name or Compose service name, or re-run setup with the container/service field filled in.
Stop and use your platform secret manager instead. The bootstrap key should not land in terminal scrollback, shell history, or scripts.
Make sure qurl-proxy.yaml exists before the bind mount. Docker creates missing host paths as directories, which makes the mounted config unreadable.
The runtime runs as UID/GID 65532. Create the state directory with mode 0700 and owner 65532:65532 before first start.
That is intentional fail-stop behavior. Pick a fresh ID or intentionally delete/recreate the connector instead of silently rolling over.
Run setup again to mint a fresh bootstrap key. Without state or a bootstrap key, the client fails closed.
Closing
Add LayerV’s hidden access layer to an existing app or API without rebuilding its infrastructure or exposing it publicly.