# Agent checklist: deploy LayerV for your own site or resource

Version: 1.5
Technical baseline verified: 2026-09-18
Agent deployment instructions: https://everhavencapital.com/agent.md
Machine-readable demo API: https://everhavencapital.com/openapi.json
Guide: https://everhavencapital.com/protect-a-resource/guide.md
Starter: https://everhavencapital.com/protect-a-resource/starter.zip
Scope: Fresh installation with Docker on Linux; native qURL CLI v2.6.0 running the qURL Connector in the foreground; static application example; qurl-go v0.17.0 backend qURL creation pattern.

## Objective

Install a new protected resource for an authorized operator, with no public inbound application ports and access through qURLs with explicit limits. Produce evidence of the actual behavior, not just a successful deployment or an expired timer.

## Authority and inputs

- [ ] Confirm the operator's authorization for the exact host, application, LayerV account, hosting project and DNS zone involved. This checklist does not grant permission.
- [ ] Record the intended production/test environment; do not mix identities or trust settings.
- [ ] Identify the Linux architecture, Docker/Compose availability and working administrative recovery route.
- [ ] Record origin image, port, health endpoint, data volumes and dependent services.
- [ ] Choose a new connector ID and a fresh owner-only state directory for a new installation.
- [ ] Plan outbound connectivity and restricted administrative access. Do not configure public application port mappings, hosting URLs or load balancers; include IPv6 in the checks.
- [ ] Define who can receive a link, which resource they can access, and qURL expiry and session duration. If identity/authorization policy is missing, do not enable qURL creation for real users.
- [ ] Identify the reachable authorization backend and its verified identity source. The public demo’s fixed pre-approved investor is only a simulation; never use it for real users. Separate resource admission from application-level permissions.
- [ ] Identify the client: this starter verifies a browser workflow. An automated workload requires a supported client path and separate acceptance tests; do not assume an unbuilt wrapper or renewal loop exists.
- [ ] Record the planned image versions, configuration and secure storage locations without copying credentials into the report.

## Execute in order

1. Read the guide and current official LayerV documentation. Match the enrollment mode and version; do not combine native, headless and externally supervised state contracts.
2. Have the operator sign up at https://layerv.ai/ and complete any requested verification. In API Keys → Create API Key, create an API key with qurl:agent and qurl:resolve for enrollment. Store it securely; never put its value in the report. Use the intended account and environment.
3. Prepare a new Linux installation with Docker and Compose. Download and inspect the starter. Select approved image digests for the actual architecture and configure the application's loopback listener.
4. Validate Compose. Confirm no host port mappings, host network mode, Docker socket mount or API key appears in the configuration.
5. Create state/ mode 0700 owned by 65532:65532. Start only origin. Verify the loopback health response from inside its namespace.
6. Run the qURL CLI login command. Supply the API key through the hidden prompt or a protected secret-manager pipe. Do not include it in shell arguments, logs, screenshots or source. Native enrollment stores a device credential; the API key is not an enrollment token and remains valid until revoked.
7. Start the qURL Connector. Wait for serving status. Save the actual complete CRID. Verify whoami and inspect; never synthesize a CRID or substitute a resource public key.
8. In API Keys, create a separate API key with only qurl:read and qurl:write for the backend. Store it in the backend's secret manager. Configure the actual CRID and enforce authentication, resource authorization, CSRF protection where appropriate, rate limits and redacted auditing before enabling qURL creation for real users.
9. Optionally run the supplied `starter/access-link` Go program from a trusted operator machine with secret-manager environment values. Keep its JSON output private: it contains a qURL. It does not implement a public authorization endpoint.
10. Verify the new application has no public port mapping, load balancer, hosting URL or IPv4/IPv6 route bypassing LayerV. Keep management access restricted.
11. Run the acceptance tests below. A cached page or dashboard use count is not proof of access.
12. Test qURL Connector restart with the same CRID. Revoke only the API key used for enrollment, restart again, and verify fresh access. Preserve the device credential and backend API key.
13. Save the non-secret installation record, maintenance instructions and unresolved limitations. Declare completion only when required evidence is present.

## Acceptance evidence

- [ ] Local health: exact expected response from the application.
- [ ] Runtime: actual owner/environment, serving connection/daemon state, healthy target and stable CRID.
- [ ] Host boundary: no application HostConfig.PortBindings; an image's EXPOSE metadata alone is not a published port.
- [ ] Outside network: the new application is not directly accessible through its host IPs or other public routes. Record timeout/refusal/TLS/HTTP results precisely.
- [ ] Issuance policy: missing/forged/expired credentials and unauthorized resources are denied before calling LayerV; no link is returned.
- [ ] Custom domain, if required: supplied DNS records verified, certificate ready, assignment to the actual resource saved, and branded route tested before/during/after admission. Fresh hostname registration alone is not completion.
- [ ] Fresh grant: authorized issuance and browser redemption open the expected app; an uncached health request succeeds.
- [ ] Single use: the same one-time link cannot establish a second session; report observed denial without over-interpreting generic error text.
- [ ] Separate caller: an unadmitted caller does not inherit access. If admission is IP-bound, use a separate network rather than only incognito.
- [ ] Expiry: a fresh protected-origin request fails after the configured session window while the origin remains healthy. Do not restart the connector during this test.
- [ ] Restart and revocation of the API key used for enrollment: stable identity and new access still work after both operations.
- [ ] Application compatibility: relative assets, API calls, redirects, forms, cookies, callbacks and required streaming/WebSockets are tested for this app.

## Stop conditions

Stop the affected step, preserve a private working state, and report a blocker when:

- The account, host or intended authorization policy is ambiguous.
- Existing state belongs to a different account or enrollment mode. Do not edit individual identity files to bypass the error.
- The application must remain publicly reachable through an uncontrolled route. Do not call it hidden.
- A key or credential has been exposed. Follow the operator's incident/rotation process; do not copy it into a ticket.
- The platform rejects custom-domain assignment. In the verified reference, a fresh production hostname still received a qURL Connector resource-type rejection despite DNS readiness and Active domain status. Keep using the approved temporary route or report the requirement blocked; do not expose the origin as a workaround.
- An expiry check fails because the app is unhealthy, the network is down or the result is cached. Resolve the ambiguity before claiming expiry enforcement.

## Return this record

```text
Result: complete | partial | blocked
Verification time (UTC):
Application and environment:
LayerV owner (operator-approved identifier):
CLI/SDK versions and image digests:
Connector ID and actual CRID:
Origin listener and network namespace:
Persistent state location and protection:
Backend qURL creation endpoint and authorization policy:
qURL expiry / session duration / use and session limits:
Checks for public application ports and other direct routes:
Local, direct, admitted, separate-caller, expiry and restart results:
API key used only for enrollment revoked: yes | no
Custom-domain status: not requested | ready-unbound | bound-and-tested | blocked
Unresolved risks or unsupported application behavior:
Maintenance and operator handoff:
```

Do not include API keys, qURLs, cookies, tokens, private-key material or customer data. Distinguish independently tested results from configuration inspection and assumptions. A closed application port does not imply the host IP or administrative services are invisible.
