Skip to content

Protect and recover an onion service

DeploymentsImpreza documentationRead as Markdown ↗

Client authorization, protection profiles and identity custody are available through the portal, REST API and hosted MCP. Existing servers require an explicit update to agent 0.6.19 or later. Local tools require MCP 0.41.0, Python SDK/CLI 0.7.0, or Go CLI 0.3.0 or later, as applicable.

An onion address identifies a Tor hidden service. It does not by itself require visitors to authenticate. Restricted discovery authorizes specific Tor client keys; application authentication remains a separate control.

Official Impreza Tor addresses

Open these addresses directly through Tor. You do not need to visit a .com address first to discover them. These are Impreza's service addresses, separate from the onion address of an application you deploy.

Service Direct onion address
Customer portal https://portal.imprezareshna326gqgmbdzwmnad2wnjmeowh45bs2buxarh5qummjad.onion/clientarea.php
REST API base URL http://api.imprezareshna326gqgmbdzwmnad2wnjmeowh45bs2buxarh5qummjad.onion
Hosted MCP endpoint http://mcp.imprezareshna326gqgmbdzwmnad2wnjmeowh45bs2buxarh5qummjad.onion/mcp
Documentation http://docs.imprezareshna326gqgmbdzwmnad2wnjmeowh45bs2buxarh5qummjad.onion/

Use Tor Browser for the portal and documentation, or a Tor-capable client for API/MCP requests. The portal uses https; API, MCP and documentation use http over Tor's encrypted onion-service connection. Preserve the scheme and endpoint path shown above; do not use an ordinary HTTP proxy or a public onion gateway. The API address is a base URL: append a route such as /v1/account. The MCP connector URL includes /mcp.

For hosted OAuth, start discovery at http://mcp.imprezareshna326gqgmbdzwmnad2wnjmeowh45bs2buxarh5qummjad.onion/.well-known/oauth-protected-resource. Use the returned issuer and authorization endpoints; the logical OAuth resource remains https://mcp.imprezahost.com/mcp. That identifier does not instruct the client to send requests outside Tor. See OAuth through Tor Browser.

Anonymous accounts and retention

You can use POST /v1/account/bootstrap on the official onion API through a Tor-capable client. Its MCP token lasts 15 minutes; renew with the returned REST key and secret on the same onion API, keeping requests through Tor. Older anonymous-account tokens issued without an expiry expire on 16 October 2026 at 21:48 UTC. Follow the renewal contract, but do not run its HTTPS example unchanged for an onion address: keep the onion API's http scheme and an explicit Tor proxy with remote hostname resolution.

The raw creation IP used for abuse limits is cleared after 24 hours on the next cron pass, with batched cleanup for any backlog. Operational idempotency metadata persists for the account lifetime, and cleanup does not erase backups. The account's privacy_report declares this retention and cleanup state. Tor transport does not change these retention rules or erase other account records.

Before you start

Use an application and server owned by your account. Reading the authorization inventory requires read; changing authorization or protection, rotating an identity, exporting it and retrieving the one-time export require manage. Portal actions require permission to manage services. The advanced onion access, profile and key-custody controls are hidden for accounts with read-only access.

Use agent 0.6.21 or later: earlier agents cannot start Tor once an upgraded tor package has reset the owner of its data directory. The agent must advertise onion-auth-v1, onion-profile-v1 or onion-custody-v1 for the corresponding operation. Update the agent explicitly using the agent update guide; upgrading the control plane does not update your server automatically.

Authorize a Tor client

From My Apps, open the application's onion client controls. Submit the public half of a locally generated X25519 key, or request a generated pair. A generated private key is shown once. Prefix the returned descriptor:x25519:<key> with the 56-character service address (without .onion) and a colon. Save the complete <service-id>:descriptor:x25519:<key> line in a .auth_private file under your Tor client's ClientOnionAuthDir, readable only by that client. Never publish it in a repository or send it to another application's operator.

The REST routes are:

Operation Route
List client names GET /v1/platform/deployments/{id}/onion/clients
Add a client POST /v1/platform/deployments/{id}/onion/clients
Revoke a client DELETE /v1/platform/deployments/{id}/onion/clients/{name}

For addition, send {"name":"laptop","pubkey":"YOUR_52_CHARACTER_BASE32_PUBLIC_KEY"} or {"name":"laptop","generate":true}. Do not combine the two key modes. The local and hosted MCP servers expose impreza_onion_auth_list, impreza_onion_auth_add and impreza_onion_auth_revoke. The hosted endpoint requires a second, argument-bound confirmation for revocation, identity export and rotation.

Revoking the final client makes the service public to Tor visitors again. Review that consequence before removing the final key. Adding or revoking a client queues an agent command; acceptance is not proof that the daemon applied the policy.

Authorization changes restart the shared Tor daemon to invalidate prior access state. Onion connections for applications on the same server may be briefly interrupted; their containers, application data and onion identities are preserved.

The agent records the previous access policy before applying a change. If a write or daemon reload fails, recovery must finish before another onion operation. If an operation reports that recovery is required, retain its command ID and ask support to inspect it; deleting state files or repeatedly submitting changes does not establish that the requested policy is active.

Choose a protection profile

POST /v1/platform/deployments/{id}/onion/profile accepts {"profile":"standard"}, hardened or max. The MCP tool is impreza_set_onion_profile. A deployment request can also specify onion_profile alongside onion:true.

hardened adds stream limits. max adds Tor proof-of-work controls and is refused when the installed Tor build does not support them. These settings do not add application login, a WAF or per-circuit rate limiting in the web proxy. A nondefault initial profile requires onion-deploy-profile-v1: the agent stages it with the identity before Tor first publishes the service. Older agents are refused before enqueue; update the agent explicitly and retry. Later profile changes remain separate operations whose completion must be checked.

Import or export an identity

For a new deployment, onion_import contains both C Tor files, encoded separately:

{
  "onion": true,
  "onion_import": {
    "secret_key_b64": "BASE64_OF_HS_ED25519_SECRET_KEY",
    "public_key_b64": "BASE64_OF_HS_ED25519_PUBLIC_KEY"
  }
}

The secret file is 96 bytes and the public file is 64 bytes. They are not a seed and public key concatenated together. The API verifies possession of the secret scalar before reserving an address, and the agent verifies the complete key pair before installation. The control plane encrypts the queued import and binds it to the account, server, deployment and command. Pending imports reserve the address; importing an address already held by another deployment is refused.

The control plane retains address reservations after failure, uninstall or rotation, so a used address is never handed to a different deployment silently. The owner can destroy a retained identity explicitly with purge; before that, contact support before moving an already-used identity to another deployment. A failed or timed-out operation is not proof that the old service has stopped.

To export, generate an X25519 recipient key locally, keep its private half, and send recipient_pubkey (base64 of its 32-byte public key) with confirm:true to POST /v1/platform/deployments/{id}/onion/export. After the command succeeds, retrieve GET /v1/platform/deployments/{id}/onion/export/{commandId} once. The MCP tools are impreza_export_onion_key and impreza_fetch_onion_key_export.

The sealed field is base64 of a NaCl anonymous sealed box. Decrypt it locally using your recipient key. The plaintext is a JSON bundle with version:1, onion, secret_key_b64 and public_key_b64; both files are needed for a later import. Losing the recipient private key makes the export unusable. A lost retrieval response cannot be fetched again; request a new export instead.

Rotate the address

Rotation changes the public address and breaks existing links. Read the current address, then send confirm:true and its exact value as confirm_address to POST /v1/platform/deployments/{id}/onion/rotate. The MCP tool is impreza_rotate_onion_key.

The agent preserves the authorization list and profile, changes the proxy route, and retains the prior identity for recovery. An interrupted operation requires reconciliation before further identity changes. A command confirmed for an old address cannot rotate a newer identity. The control plane commits the new address and command receipt together, checks current ownership again, and rejects a changed receipt on retry. Retrying an export result cannot restore an already retrieved ciphertext.

Keep a branch preview private

Requires agent 0.6.20+ and local MCP 0.42.0+. The REST API and hosted MCP expose the same creation options.

A dark preview exists to share work before it ships. Explicit creation can restrict the preview's own onion with the same client authorization a production service uses: POST /v1/platform/deployments/custom/{id}/previews accepts private:true — minting one reviewer keypair whose private key is shown exactly once in the response — or an explicit onion_clients list of reviewer public keys (up to 16). The MCP tool is impreza_create_preview with the same fields. This requires onion-private-preview-v1; update the agent first. Authorization is installed before the first descriptor publication. After deployment completes, save the one-time reviewer key locally in a file under your Tor client's ClientOnionAuthDir, prefixed with the service address without .onion: <56-character-service-id>:descriptor:x25519:<private-key>. Never share that private key or send it back to the API.

Automatic previews created by repository pushes stay public: the push webhook has no channel that could hand a generated private key to the customer. A preview is either private or password-protected, not both. On a preview that already exists, privacy is managed with the regular client authorization commands on the preview's own deployment id. Retiring a private preview removes its reviewer list and uninstalls it. The agent may retain recovery key material under its retention policy.

Destroy a retained identity

Requires agent 0.6.20+, local MCP 0.42.0+, or Go CLI 0.3.1+, as applicable.

Rotation and uninstall keep recovery copies: the agent parks the prior key material on the host, and an imported address stays reserved platform-wide. Agent-side purge irreversibly deletes the matching retained copies on that host. Prior exports and external backups are unaffected. A queued command is not proof of deletion; wait for its successful completion.

Send confirm:true and the retained address verbatim as confirm_address to POST /v1/platform/deployments/{id}/onion/purge. Two paths exist:

  • a prior identity of a running deployment (for example an address left by a rotation) queues an agent command that deletes every parked copy matching that address and releases the reservation when the agent reports success. The agent refuses to purge the deployment's current address;
  • the own address of an already uninstalled deployment is released immediately from the control-plane records, with no agent command, because the server may no longer exist. This released result does not verify deletion of keys on the former host; retained copies may still restore it.

The MCP tool is impreza_purge_onion_key; the Go CLI is impreza platform onion-key purge. Purging is a manage operation and, on the agent path, requires an agent that announces onion-purge-v1. Rotation receipts survive a purge: they carry no key material and only prove that a past rotation happened.

Advertise the onion to Tor Browser

Deployments that serve both a clearnet domain and an onion automatically send Onion-Location: http://<address>.onion/ on their clearnet HTTPS responses. Tor Browser shows the ".onion available" hint and offers the switch; other browsers ignore the header. Rotating the address rewrites the advertised onion automatically. The header is only meaningful on a secure clearnet context, so it is not emitted on plain-HTTP hostnames.

No configuration is required. It is active for every dual-stack deployment on agents 0.6.19 and later.

Verify and troubleshoot

Uninstall success requires route and hidden-service cleanup to finish. If cleanup fails, retry the operation; the absence of application files does not prove that its network routes were removed. Parked identity keys remain available for explicit recovery under the retention policy.

Check the command outcome and the current deployment address. Test through Tor with an authorized client and again with a separate unauthorized client. Knowing the address must not permit access through the server's public HTTP listener.

Each server reports the Tor daemon it runs (version, image and whether it is running) with every heartbeat. GET /v1/platform/servers exposes it, and the portal server card shows it. When the max profile is refused, the reason is the running Tor build lacking the proof-of-work module: update the agent, which carries the pinned Tor image, and retry.

To connect the local MCP to an onion API URL, configure IMPREZA_PROXY with an explicit socks5://host:port proxy. Tor commonly listens on port 9050; Tor Browser commonly uses 9150. The client does not fall back to direct DNS or clearnet when the proxy is unavailable. The Go SDK similarly requires UseTor or an explicit proxy.

For the hosted MCP connector, discover OAuth metadata through the same onion endpoint you intend to use. Its authorization server and consent redirect must identify the same onion issuer. The logical resource remains https://mcp.imprezahost.com/mcp, including when transported through Tor; do not rewrite it to the onion URL. A different issuer or resource is a connection error, not a reason to disable the client's validation.

Onion webhook delivery uses SOCKS hostname resolution even when the worker environment contains proxy bypass rules. It refuses redirects and discards the response body; a failed Tor connection remains a failed delivery.

For normal deployment and recovery workflows, see deployment safety and the REST API tutorial.

OAuth through Tor Browser

Use an OAuth client that explicitly supports the onion endpoint and a Tor proxy. Opening the consent page in Tor Browser does not route the client's token exchange or MCP requests through Tor automatically. Keep issuer, resource, state and PKCE validation enabled. See MCP connection steps.

Before approving, check the app name, redirect target and permission checkboxes. Read and Deploy are selected by default; Manage is not. For read-only access, uncheck Deploy, even when the authorization URL requests scope=read. The selected permissions determine the grant. Disconnect an unwanted grant from Impreza API → Connected Apps and authorize again with the intended permissions.

Some desktop clients receive the browser response at http://127.0.0.1:PORT/. This address belongs to your computer: the client must be running there and listening on the exact registered port. A browser on another device cannot reach that listener. Use the callback URL supplied by your client; do not invent a port.

If consent stays open or the return is blocked:

  1. Confirm that your local client is still waiting for authorization. Start a new login if it timed out; do not reuse an old authorization link.
  2. If Tor Browser cannot reach the local listener, record the existing network.proxy.no_proxies_on value in about:config. If needed, temporarily add only 127.0.0.1 to that comma-separated list. This allows a direct local connection; it does not send the callback through Tor. Restore the original value when the login is complete.
  3. NoScript may separately block the page's local-network request. Only when you initiated the login and verified the exact loopback destination, permit that request temporarily for the consent page. Do not grant all sites LAN access or disable NoScript globally. Revoke the temporary permission afterwards.

A callback-received message confirms only that the browser reached the local client. Wait for the client to confirm the token exchange and MCP connection. Never paste a callback URL containing code=, tokens or credentials into a chat. If it fails, retain only the redacted error and start a fresh login.

NoScript's permission documentation explains its temporary, site-specific permissions and separate LAN capability. Browser settings and client support can differ; these steps do not establish compatibility with every MCP client.

Application runtime through Tor

Available with agent 0.6.20+ and local MCP 0.42.0+. This is an optional setting for a new custom image or source deployment. It is separate from an inbound .onion address and from connecting an AI client through Tor.

The target agent must advertise tor-egress-v1, and the server needs Docker Engine 28 or newer with IPv6 and isolated bridge gateway support. In My Apps → Deploy a custom app, select Route application runtime traffic through Tor. Through impreza_deploy_custom or POST /v1/platform/deployments/custom, set tor_egress: true with image or Dockerfile/source mode. Saved deployment reviews retain the choice; redeploys and previews inherit it. Updating an agent is an explicit customer action: see agent updates.

{
  "name": "tor-client",
  "agent_id": "YOUR_AGENT_ID",
  "mode": "image",
  "image": "YOUR_SOCKS_CAPABLE_IMAGE",
  "target_port": 8080,
  "tor_egress": true
}

Application containers join a dedicated internal network with no host bridge address or published application port. Managed ingress connects to that network. A separate per-app Tor sidecar joins both the isolated network and its own uplink; its SOCKS listener is not published on the host. The agent verifies the network's ownership and isolation settings before replacing containers. Unsupported Docker versions or conflicting networks fail the deployment instead of weakening it.

Your application must support socks5h://tor-socks:9050. The agent sets upper- and lower-case ALL_PROXY, HTTP_PROXY and HTTPS_PROXY variables, with DNS resolved by Tor. These variables are not automatically supported by every HTTP library; configure an explicit SOCKS-capable client when necessary. Docker service-name resolution remains available; ordinary external DNS and direct IPv4/IPv6 egress are blocked. Loopback addresses are excluded from proxy variables.

Verify a request from the application using its actual HTTP client. A Tor-capable client should complete it; disabling its proxy or stopping its Tor sidecar should fail without direct fallback. Application ingress should remain available. Check the deployment result and logs after agent or container restarts. A running container alone does not prove Tor has finished bootstrapping.

Limits: this is runtime TCP egress, not transparent interception, UDP support, or an anonymity guarantee. Source retrieval, image pulls and builds use the server's ordinary connection. Client browsers also use their own connections. Imported Compose/manifests, catalog installs and external service-binding networks are not supported by this option. Do not disable isolation to make an incompatible application work. The sidecar uses a pinned image; future security updates require a reviewed image/agent release and an explicit customer redeploy.