# SDK Reference: Confidential HTTP Client
Source: https://docs.chain.link/cre/reference/sdk/confidential-http-client-go
Last Updated: 2026-02-10

> For the complete documentation index, see [llms.txt](/llms.txt).

The [Confidential HTTP](/cre/capabilities/confidential-http-go) Client lets you make privacy-preserving requests to external APIs from your workflow. Unlike the regular [`http.Client`](/cre/reference/sdk/http-client), the request executes inside a secure enclave, secrets are injected via templates, and responses can be optionally encrypted.

- For use cases and a conceptual overview, see [The Confidential HTTP Capability](/cre/capabilities/confidential-http-go)
- **Guide:** [Making Confidential Requests](/cre/guides/workflow/using-confidential-http-client/making-requests-go)

> **CAUTION: Do not assume sensitive values are always enclave-resolved**
>
> **Credential isolation** applies when sensitive values are listed in **`VaultDonSecrets`** and referenced only with **`{{.secretName}}` placeholders**, so plaintext is resolved inside the enclave. Values you interpolate into headers or body as ordinary workflow strings—including from **`runtime.GetSecret()`** and similar APIs—are resolved in **Workflow DON** execution and follow a different trust boundary. See [Making Confidential Requests](/cre/guides/workflow/using-confidential-http-client/making-requests-go#step-4-implement-the-request-logic) for the intended pattern.

## Quick reference

| Method                                     | Description                        |
| ------------------------------------------ | ---------------------------------- |
| [`client.SendRequest`](#clientsendrequest) | Makes a confidential HTTP request. |

## Core types

### `confidentialhttp.ConfidentialHTTPRequest`

The top-level request type that combines an HTTP request with Vault DON secrets and encryption settings.

| Field             | Type                  | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |
| ----------------- | --------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `Request`         | `*HTTPRequest`        | The HTTP request to execute inside the enclave. See [`HTTPRequest`](#confidentialhttphttprequest).                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| `VaultDonSecrets` | `[]*SecretIdentifier` | Vault DON secrets for enclave-only `{{.key}}` substitution in the request ([`SecretIdentifier`](#confidentialhttpsecretidentifier)). Use this when credentials or other sensitive template values must stay out of Workflow DON execution—not replaceable by pasting `runtime.GetSecret()` output into headers or body. See [what stays confidential](/cre/capabilities/confidential-http-go#whats-kept-confidential) and [Making Confidential Requests](/cre/guides/workflow/using-confidential-http-client/making-requests-go#step-4-implement-the-request-logic). |

### `confidentialhttp.HTTPRequest`

Defines the HTTP request that will be executed inside the enclave.

| Field                  | Type                       | Description                                                                                                                            |
| ---------------------- | -------------------------- | -------------------------------------------------------------------------------------------------------------------------------------- |
| `Url`                  | `string`                   | The URL of the API endpoint.                                                                                                           |
| `Method`               | `string`                   | The HTTP method (e.g., `"GET"`, `"POST"`).                                                                                             |
| `Body`                 | `isHTTPRequest_Body`       | The request body. Use `HTTPRequest_BodyString` for string templates or `HTTPRequest_BodyBytes` for raw bytes.                          |
| `MultiHeaders`         | `map[string]*HeaderValues` | Request headers. Supports multiple values per key and template syntax for secret injection.                                            |
| `TemplatePublicValues` | `map[string]string`        | Public (non-secret) values used to fill template placeholders in the body and headers.                                                 |
| `CustomRootCaCertPem`  | `[]byte`                   | Optional custom root CA certificate (PEM format) for verifying the external server's TLS certificate.                                  |
| `Timeout`              | `*durationpb.Duration`     | Optional request timeout.                                                                                                              |
| `EncryptOutput`        | `bool`                     | If `true`, encrypts the response body before it leaves the enclave. See [Response encryption](#response-encryption). Default: `false`. |

#### Setting the request body

The `Body` field is a `oneof` type with two options:

**String template (recommended for secret injection):**

```go
Body: &confidentialhttp.HTTPRequest_BodyString{
	BodyString: `{"auth": "{{.myApiKey}}", "action": "getData"}`,
},
```

**Raw bytes:**

```go
Body: &confidentialhttp.HTTPRequest_BodyBytes{
	BodyBytes: []byte(`{"action": "getData"}`),
},
```

### `confidentialhttp.HTTPResponse`

The response returned from the enclave after the HTTP request completes.

| Field          | Type                       | Description                                                                                                                          |
| -------------- | -------------------------- | ------------------------------------------------------------------------------------------------------------------------------------ |
| `StatusCode`   | `uint32`                   | The HTTP status code.                                                                                                                |
| `Body`         | `[]byte`                   | The response body. If `EncryptOutput` is `true`, this contains the encrypted body (see [Response encryption](#response-encryption)). |
| `MultiHeaders` | `map[string]*HeaderValues` | The HTTP response headers.                                                                                                           |

### `confidentialhttp.SecretIdentifier`

Identifies a secret stored in the Vault DON.

| Field       | Type      | Description                                                                                                       |
| ----------- | --------- | ----------------------------------------------------------------------------------------------------------------- |
| `Key`       | `string`  | The logical name of the secret. Must match the template placeholder (e.g., `"myApiKey"` matches `{{.myApiKey}}`). |
| `Namespace` | `string`  | The secret namespace.                                                                                             |
| `Owner`     | `*string` | Optional. The owner address for the secret.                                                                       |

### `confidentialhttp.HeaderValues`

Represents multiple values for a single HTTP header key.

| Field    | Type       | Description                                                                                      |
| -------- | ---------- | ------------------------------------------------------------------------------------------------ |
| `Values` | `[]string` | The header values. Supports template syntax for secret injection (e.g., `"Basic {{.myToken}}"`). |

## Making requests

### `client.SendRequest`

Makes a confidential HTTP request. The request executes inside a secure enclave, so unlike the regular HTTP client, there is no need to wrap this call in `cre.RunInNodeMode`.

**Signature:**

```go
func (c *Client) SendRequest(runtime cre.Runtime, input *ConfidentialHTTPRequest) cre.Promise[*HTTPResponse]
```

**Parameters:**

- `runtime`: The `cre.Runtime` from your trigger callback.
- `input`: A `*ConfidentialHTTPRequest` containing the request and secrets.

**Returns:**

- `cre.Promise[*HTTPResponse]`

**Example:**

```go
client := &confidentialhttp.Client{}
resp, err := client.SendRequest(runtime, &confidentialhttp.ConfidentialHTTPRequest{
	Request: &confidentialhttp.HTTPRequest{
		Url:    config.URL,
		Method: "POST",
		Body:   &confidentialhttp.HTTPRequest_BodyString{BodyString: `{"auth": "{{.apiKey}}"}`},
		MultiHeaders: map[string]*confidentialhttp.HeaderValues{
			"Content-Type":  {Values: []string{"application/json"}},
			"Authorization": {Values: []string{"Basic {{.apiKey}}"}},
		},
		EncryptOutput: false,
	},
	VaultDonSecrets: []*confidentialhttp.SecretIdentifier{
		{Key: "apiKey"},
	},
}).Await()
if err != nil {
	return Result{}, err
}
// Parse resp.Body...
```

**Guide:** [Making Confidential Requests](/cre/guides/workflow/using-confidential-http-client/making-requests-go)

## Template syntax

Secrets are injected into the request body and headers using Go template syntax: `{{.secretName}}`. The placeholder name must match the `Key` field in the corresponding `SecretIdentifier`.

**Body template:**

```go
Body: &confidentialhttp.HTTPRequest_BodyString{
	BodyString: `{"apiKey": "{{.myApiKey}}", "method": "{{.method}}", "params": []}`,
},
```

**Header template:**

```go
MultiHeaders: map[string]*confidentialhttp.HeaderValues{
	"Authorization": {Values: []string{"Basic {{.myCredential}}"}},
},
```

### `TemplatePublicValues` (optional)

Every `{{.placeholder}}` in your body or headers is resolved inside the enclave. By default, placeholders are filled with **secrets** from `VaultDonSecrets`. But sometimes you have a placeholder value that isn't secret — for example, an RPC method name or a public parameter. That's what `TemplatePublicValues` is for: it lets you inject **non-secret** values into the same template.

This is purely a convenience. You could always hardcode the value directly in the body string instead:

```go
// These two are equivalent:

// Option 1: hardcoded in the body string
Body: &confidentialhttp.HTTPRequest_BodyString{BodyString: `{"method": "eth_blockNumber", "auth": "{{.apiKey}}"}`}

// Option 2: using TemplatePublicValues
Body: &confidentialhttp.HTTPRequest_BodyString{BodyString: `{"method": "{{.method}}", "auth": "{{.apiKey}}"}`}
TemplatePublicValues: map[string]string{"method": "eth_blockNumber"}
```

`TemplatePublicValues` is useful when you want to keep the template generic and pass in dynamic values (e.g., from config) without string concatenation.

**Example with both secret and public values:**

```go
Request: &confidentialhttp.HTTPRequest{
	Url:    config.URL,
	Method: "POST",
	Body:   &confidentialhttp.HTTPRequest_BodyString{BodyString: `{"method": "{{.rpcMethod}}", "auth": "{{.apiKey}}"}`},
	TemplatePublicValues: map[string]string{
		"rpcMethod": config.RPCMethod,   // dynamic value from config, not a secret
	},
},
VaultDonSecrets: []*confidentialhttp.SecretIdentifier{
	{Key: "apiKey"},   // secret, from Vault DON
},
```

In this example, `{{.rpcMethod}}` is resolved from `TemplatePublicValues` (a dynamic, non-secret value from your workflow config) and `{{.apiKey}}` is resolved from the Vault DON (a secret). Both are resolved inside the enclave.

## Response encryption

The `EncryptOutput` field controls whether the response body is encrypted before leaving the enclave.

| `EncryptOutput`   | Secret key provided                                      | Behavior                                                      |
| ----------------- | -------------------------------------------------------- | ------------------------------------------------------------- |
| `false` (default) | —                                                        | Response returned unencrypted.                                |
| `true`            | `san_marino_aes_gcm_encryption_key` in `VaultDonSecrets` | Response AES-GCM encrypted with your symmetric key.           |
| `true`            | No key provided                                          | Response TDH2 encrypted with the Vault DON master public key. |

**AES-GCM encryption** is the recommended approach. Store a 256-bit (32-byte) AES key as a Vault DON secret with the identifier `san_marino_aes_gcm_encryption_key`, then decrypt the response in your own secure backend.

The encrypted response body is structured as `nonce || ciphertext || tag`.

For a complete decryption example, see the [Making Confidential Requests guide](/cre/guides/workflow/using-confidential-http-client/making-requests-go#response-encryption).