> For the complete documentation index, see [llms.txt](https://docs.enclaive.cloud/virtual-hsm/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.enclaive.cloud/virtual-hsm/tutorials/vhsm-proxy-quickstart.md).

# vHSM Proxy quickstart

vHSM Proxy is designed to simplify and accelerate the adoption of vHSM by providing a scalable, lightweight way for applications to interact with vHSM server seamlessly. Acting as an API proxy, vHSM Proxy streamlines authentication and token management, enabling applications to integrate with vHSM without handling complex auth workflows directly.

vHSM Proxy runs as a client-side daemon and offers the following key capabilities:

* **Auto-Auth**: Automatically authenticates to vHSM and handles the lifecycle of dynamic secrets, including token acquisition and renewal.
* **API Proxy**: Transparently proxies requests to vHSM’s API, with the option to use—or enforce the use of—an automatically authenticated token for all client interactions.
* **Caching**: Supports local caching of responses for newly created tokens and leased secrets, reducing latency and minimizing redundant requests. It also manages the renewal of cached tokens and leases automatically.

#### Prerequisites <a href="#prerequisites" id="prerequisites"></a>

* [Install vHSM CLI](/virtual-hsm/documentation/setup.md)
* [Install vHSM and start a Dev server](/virtual-hsm/documentation/setup/installation.md)
* Install [jq](https://jqlang.org/) for better readability of the JSON output

1\. Create a directory for storing test files and configuration.

```bash
mkdir -p $HOME/vhsm-test && cd $HOME/vhsm-test
```

2\. Create a mock dataset `data.json` representing a customer record, using an editor of your choice:

```bash
{
   "organization": "Enclaive",
   "customer_id": "ABXX2398YZPIE7391",
   "region": "US-West",
   "zip_code": "94105",
   "type": "premium",
   "contact_email": "alice@enclaive.com",
   "status": "active"
}
```

3. Upload the test data to the vHSM KV v2 secrets engine:

```bash
vhsm kv put secret/customers/enclaive @data.json
```

4\. Create the proxy configuration file `vhsm-proxy-config.json`  that defines API endpoint for the client application to send requests to rather than `VAULT_ADDR`.&#x20;

```bash
pid_file = "./pidfile"

vault {
   address = "http://127.0.0.1:8200"
   tls_skip_verify = true
}

auto_auth {
   method {
      type = "token_file"
      config = {
         token_file_path = "$HOME/.vault-token"
      }
   }
   sink "file" {
      config = {
            path = "$HOME/vault-proxy"
      }
   }
}

listener "tcp" {
   address     = "127.0.0.1:8100"
   tls_disable = true
}

api_proxy {
   use_auto_auth_token = true
   enforce_consistency = "always"
}

```

> **Note:**  The `vault` and `auto_auth` stanzas in the vHSM Proxy and vHSM Agent configurations are identical; however, you must define `listener` and `api_proxy` stanzas for vHSM Proxy.

5. Start the vHSM Proxy.

```
vhsm proxy -config=vault-proxy-config.json
```

The output is similar to:

```
==> vHSM Proxy started! Log data will stream in below:

==> vHSM Proxy configuration:

           Api Address 1: http://127.0.0.1:8100
                     Cgo: disabled
               Log Level: 
                 Version: Vhsm v1.3.7-0, built 2025-01-29T15:11:42Z
             Version Sha: 00d245ed8143844db6761fd947433aab237f914f+CHANGES

2025-03-10T18:28:43.946+0530 [INFO]  proxy.sink.file: creating file sink
2025-03-10T18:28:43.947+0530 [INFO]  proxy.sink.file: file sink configured: path=/Users/rkodhandapani/vault-token-via-agent mode=-rw-r-----
2025-03-10T18:28:43.947+0530 [INFO]  proxy.sink.server: starting sink server
2025-03-10T18:28:43.947+0530 [INFO]  proxy.auth.handler: starting auth handler
2025-03-10T18:28:43.947+0530 [INFO]  proxy.auth.handler: authenticating
2025-03-10T18:28:43.949+0530 [INFO]  proxy.auth.handler: authentication successful, sending token to sinks
2025-03-10T18:28:43.949+0530 [INFO]  proxy.auth.handler: not starting token renewal process, as token has unlimited TT
```

6. Open another command terminal and send an API request to the vHSM Proxy.

   Read the secrets at `secret/customers/enclaive` via the proxy address.

   ```
   curl -s http://127.0.0.1:8100/v1/secret/data/customers/enclaive \
      | jq -r ".data.data"
   ```

   Output:

   ```
   {
      "contact_email": "alice@enclaive.com",
      "customer_id": "ABXX2398YZPIE7391",
      "organization": "Enclaive",
      "region": "US-West",
      "status": "active",
      "type": "premium",
      "zip_code": "94105"
   }
   ```

   A token was automatically attached to the request by the vHSM Proxy because you set the `use_auto_auth_token` parameter to `true` in the configuration.

7. Read the secrets again. This time, vHSM's Proxy returns the cached secrets.

   ```
   curl --verbose -s http://127.0.0.1:8100/v1/secret/data/customers/enclaive \
      | jq -r ".data.data"
   ```

   Use the `--verbose` or `-v` option with the cURL command so that you can see more detail.

   ```
   *   Trying 127.0.0.1:8100...
   * Connected to 127.0.0.1 (127.0.0.1) port 8100 (#0)
   > GET /v1/secret/data/customers/enclaive HTTP/1.1
   > Host: 127.0.0.1:8100
   > User-Agent: curl/8.1.2
   > Accept: */*
   > 
   < HTTP/1.1 200 OK
   < Cache-Control: no-store
   < Content-Length: 465
   < Content-Type: application/json
   < Date: Mon, 10 Mar 2025 15:43:34 GMT
   < Strict-Transport-Security: max-age=31536000; includeSubDomains
   < X-Cache: MISS
   < 
   { [465 bytes data]
   * Connection #0 to host 127.0.0.1 left intact
   {
     "contact_email": "alice@enclaive.com",
     "customer_id": "ABXX2398YZPIE7391",
     "organization": "Enclaive",
     "region": "US-West",
     "status": "active",
     "type": "premium",
     "zip_code": "94105"
   }
   ```

8. Update the secrets to see what happens.

   ```
   vhsm kv patch secret/customers/enclaive "customer_since"="2011"
   ```

9. Read the secrets again through vHSM Proxy.

   ```
   curl --verbose http://127.0.0.1:8100/v1/secret/data/customers/enclaive \
      | jq -r ".data.data"
   ```

   The output is similar to:

   ```
   * Connected to 127.0.0.1 (127.0.0.1) port 8100 (#0)
   > GET /v1/secret/data/customers/enclaive HTTP/1.1
   > Host: 127.0.0.1:8100
   > User-Agent: curl/8.1.2
   > Accept: */*
   > 
   < HTTP/1.1 200 OK
   < Cache-Control: no-store
   < Content-Length: 489
   < Content-Type: application/json
   < Date: Mon, 10 Mar 2025 15:52:55 GMT
   < Strict-Transport-Security: max-age=31536000; includeSubDomains
   < X-Cache: MISS
   < 
   { [489 bytes data]
   100   489  100   489    0     0  58612      0 --:--:-- --:--:-- --:--:--  238k
   * Connection #0 to host 127.0.0.1 left intact
   {
     "contact_email": "alice@enclaive.com",
     "customer_id": "ABXX2398YZPIE7391",
     "customer_since": "2011",
     "organization": "Enclaive",
     "region": "US-West",
     "status": "active",
     "type": "premium",
     "zip_code": "94105"
   }
   ```

10. Press **Ctrl + C** to stop the running vHSM Proxy.

<br>


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.enclaive.cloud/virtual-hsm/tutorials/vhsm-proxy-quickstart.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
