Skip to main content

Connector setup guide

Make private resources available, not public.

The Enterprise connector lets approved people, apps, and agents access an existing app or API without exposing it to the public internet.

  • Docker & Compose
  • ECS / Fargate
  • Kubernetes

Publishing a local app?

The CLI is simpler for local development, demos, and single-machine services.

Deploying the standalone connector beside a service? LayerV generates its configuration for your account. Contact LayerV to set one up.

Operate

Restarts, recovery, and state

01

An enrollment token is minted

You mint a one-shot enrollment token bound to this connector id and stage it as a read-only file for first registration.

02

The connector registers once

On first start, the qURL CLI presents the enrollment token, registers its persistent NHP keypair, and stores the device credential the platform mints under the state directory at /var/lib/qurl.

03

Restarts use state

The enrollment token is consumed by that first success — remove the token file. Future restarts authenticate with the device credential in the mounted state directory, and fail closed if that state is missing.

04

Runtime routing stays dynamic

The connector knocks through NHP and receives the public address at runtime; customers do not configure internal LayerV hosts.

Audit logging

The connector emits a structured record for each bootstrap, knock, login, proxy, and teardown decision. It is on by default and mirrored into your runtime logs; route it to a JSONL file when you need forensic retention.

Key storage

The default file provider stores the connector private key in the state directory at mode 0600. Choose aws-kms or gcp-kms when durable state must move without plaintext key files; state then holds private_key.sealed.json instead.

Standard connector onboarding stays simple. AWS Nitro and GCP Confidential Space are an optional advanced tier, for customers whose security owner requires cloud attestation before KMS releases the connector private key.

Optional Docker env
# 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

# 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/1234abcd-... \
-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.com

# 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

KMS rollout rules

  • Keep /dev/shm available, or set LAYERV_NHP_RUNTIME_DIR to another tmpfs-backed path. Do not use disk-backed runtime dirs in production.
  • Grant the workload principal both encrypt and decrypt permission before first boot; the client verifies decryptability before removing plaintext state.
  • To convert an existing file-provider state volume, set LAYERV_ALLOW_KEY_MIGRATION=true for the migration restart only, then remove it after private_key.sealed.json is written.
  • Treat migration as one-way for that agent identity. The sealed blob and cloud KMS key must be backed up and recoverable together.
  • KMS sealing protects copied state volumes that lack IAM decrypt rights; it is not a host-compromise boundary.

What the API does and does not tell you

  • The API Connectors tag — GET /v1/connectors/installations — lists third-party integrations (Slack and others), not Connector sidecars. The dashboard shows them under Integrations.
  • GET and PUT /v1/resources/{id}/sharing report lifecycle status only — desired_state on|off, serving_epoch, and connection_state stopped|connecting|serving — not configuration.

When a call fails, the error catalog lists the code, status, cause, and fix.

Reference — Resource types

What kinds of resources exist

qURL protects three kinds of resource, and only one of them is served by a Connector. The type decides how access is granted and which minting options apply.

Resource type to access mechanism
TypeMeaningHow it is reached
urla target URLThe default resource, reached through qURL’s reverse proxy. Works for browsers and agents. Not a Connector resource.
tunnelan Enterprise connectorA resource served by a Connector, reached through the Connector session (NHP-gated), so the origin needs no inbound port. Supports target_path when minting a link, so a link can point at a path or query on the resource host.
transitcontent uploaded through an integrationConnector-owned uploads. Not listed via /v1/resources; use connector installation operations for their reports.

Only type=tunnel accepts target_path when minting a link.

Reference — Lifecycle

Connector lifecycle and connection state

GET /v1/resources/{id}/sharing, and PUT to the same path to change the desired state, report lifecycle status only. They never return configuration.

Fields returned by the sharing endpoint
FieldValuesMeaning
resource_idstringThe resource key retained for compatibility.
cridstringThe permanent, location-independent identifier.
desired_stateon | offThe lifecycle state you asked for.
serving_epochint64Rotates whenever the lifecycle state changes.
connection_statestopped | connecting | servingserving requires at least one authenticated Connector connection that is ready to carry traffic.

Repeating the same desired state is idempotent and preserves serving_epoch. Changing state rotates the epoch, so connections from the previous lifecycle stop serving.

01

Enroll once

The Connector presents its enrollment token and the platform mints the device credential. That durable identity is what every restart reuses.

02

The resource is bound

Enrollment binds the Connector resource to that identity.

03

Set sharing on

PUT /v1/resources/{id}/sharing with desired_state: on.

04

Poll until serving

GET the same path until connection_state is serving.

If both the durable state and the enrollment token are gone, the Connector will not silently register a second identity. It fails closed and must be enrolled again.

Reference — Credentials

Which credential can do what

Four credential kinds show up around a Connector. Each has a different origin and a different set of allowed operations.

Credential capabilities
CredentialWhat it isWhat it can do
api_keyAccount API key. Carries scopes.With the qurl:agent scope, mints enrollment tokens (target: agent or connector). Its scopes decide what it may do.
enrollment_tokenA one-shot token bound to one target.Enrolls exactly one target (agent or connector). Single-use. Cannot create credentials.
device credentialCreated by the platform at enrollment. Durable. Never creatable through the API.The machine’s durable identity and what every restart reuses. Appears in credential listings so it can be revoked.
JWTThe console and session credential (Auth0).Some operations are JWT-only — Usage, Customer, and Billing tags, and PATCH /v1/api-keys/{key_id}. API keys cannot update API keys.

Reference — Plans and limits

Plans and limits

Verified limits that apply across plans.

Plan limits
LimitValue
Access-link lifetime (expires_in / expires_at on link creation and extension)Minimum 1 minute, maximum 30 days on all plans.
Enrollment tokens and child API keysMaximum 24 hours (default 24 hours).
GET /v1/quota rate_limits.max_expiry_seconds2592000 (30 days) on all customer plans.
API-key plan limit (api_key_limit, 403)free 3, growth 50.

connector_disabled is a 403 meaning Connector operations are temporarily unavailable. It is an availability state, not an authorization failure.

Reference — Errors

Error catalog

Each API error carries a code, an HTTP status, a cause, and the fix.

API error codes
CodeHTTPMeaningFix
invalid_input400Mismatched fields for the requested kind (for example scopes on an enrollment token, or target/claims/expires_in on an API key, or more than one claim).Send only the fields that kind accepts.
invalid_session_duration400The requested session duration is not accepted.Use a valid duration or omit it.
bootstrap_key_consumed409The enrollment token was already consumed by another enrollment. It is terminal.Mint a new token. Never retry the same one concurrently.
slug_in_use409A Connector resource with that slug already exists.Use find_or_create: true or choose another slug.
resource_alias_mismatch409The alias does not match the existing resource.Reuse the existing alias or choose a different one.
resource_type_conflict409The existing resource has a different type.Use the matching resource or a different identifier.
connector_disabled403Connector operations are currently unavailable.Retry later or verify Connector availability.
account_frozen403The account is frozen.Resolve the billing or account state.
api_key_limit403Plan credential limit reached (free 3, growth 50).Revoke an unused key or upgrade.
knock_failed502Failed to grant network access; the token may have been consumed.Mint a fresh link and retry.

Reference — Naming

Naming: say what you mean

A few terms in the API and the console sound alike. These are the distinctions.

Enterprise connector (sidecar) vs connector installation
The sidecar runs next to your service. A “connector installation” in GET /v1/connectors/installations is a third-party integration (Slack, storage accounts) — a different thing. In the dashboard, sidecars are under Connectors and installations under Integrations.
sharing (lifecycle) vs share (verb)
desired_state and connection_state on /v1/resources/{id}/sharing are lifecycle. POST /v1/resources/{id}/share mints an access link.
resource / qURL / link / token / session
A resource is the protected thing. A qURL is the access link to it. A token is what the link carries. A session is the admitted access window.
resource_id / crid / slug / alias
resource_id is the resource key retained for compatibility. crid is the permanent, location-independent identifier — prefer it. slug is the stable Connector name. alias is a memorable handle.
agent (sidecar device) vs AI agent
Here “agent” means a connector or device identity. An AI agent is a program that can call the API.

Pilot LayerV

Tell us what to protect, and we’ll scope a pilot.

Enterprise starts with a scoped, paid pilot on one application, typically 60 to 90 days, credited in full toward year one if you convert within 60 days. Then an annual package sized to what you protect. Not per seat.