SDK Reference: Confidential HTTP Client
The Confidential HTTP Client lets you make privacy-preserving requests to external APIs from your workflow. Unlike the regular HTTPClient, 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
- Guide: Making Confidential Requests
Quick reference
| Method | Description |
|---|---|
sendRequest | Makes a confidential HTTP request. |
Core types
ConfidentialHTTPRequest / ConfidentialHTTPRequestJson
The top-level request type that combines an HTTP request with Vault DON secrets and encryption settings.
Field | Type | Description |
|---|---|---|
request | HTTPRequest | HTTPRequestJson | The HTTP request to execute inside the enclave. See HTTPRequest. |
vaultDonSecrets | SecretIdentifier[] | SecretIdentifierJson[] | List of secrets to fetch from the Vault DON and make available in the enclave. See SecretIdentifier. |
HTTPRequest / HTTPRequestJson
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"). |
bodyString | string (optional) | The request body as a string template. Use this for secret injection with {{.secretName}} placeholders. |
bodyBytes | Uint8Array | string (optional) | The request body as raw bytes (base64-encoded in JSON format). |
multiHeaders | { [key: string]: HeaderValues } (optional) | Request headers. Supports multiple values per key and template syntax for secret injection. |
templatePublicValues | { [key: string]: string } (optional) | Public (non-secret) values used to fill template placeholders in the body and headers. |
customRootCaCertPem | Uint8Array | string (optional) | Optional custom root CA certificate (PEM format) for verifying the external server's TLS certificate. |
timeout | Duration | DurationJson (optional) | Optional request timeout (e.g., "5s"). |
encryptOutput | boolean (optional) | If true, encrypts the response body before it leaves the enclave. See Response encryption. Default: false. |
HTTPResponse / HTTPResponseJson
The response returned from the enclave after the HTTP request completes.
Field | Type | Description |
|---|---|---|
statusCode | number | The HTTP status code. |
body | Uint8Array | string (base64) | The response body. If encryptOutput is true, this contains the encrypted body (see Response encryption). |
multiHeaders | { [key: string]: HeaderValues } | The HTTP response headers. |
SecretIdentifier / SecretIdentifierJson
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) | Optional. The owner address for the secret. |
HeaderValues / HeaderValuesJson
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
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 runtime.runInNodeMode().
Signature:
sendRequest(
runtime: Runtime<unknown>,
input: ConfidentialHTTPRequest | ConfidentialHTTPRequestJson
): { result: () => HTTPResponse }
Parameters:
runtime: TheRuntimeinstance from your trigger handler.input: AConfidentialHTTPRequestorConfidentialHTTPRequestJsonobject containing the request and secrets.
Returns:
An object with a .result() method that blocks until the request completes and returns the HTTPResponse.
Example:
import { ConfidentialHTTPClient, ok, json, type Runtime } from "@chainlink/cre-sdk"
type Config = { url: string; owner: string }
type APIResult = { data: string }
const onCronTrigger = (runtime: Runtime<Config>): string => {
const confHTTPClient = new ConfidentialHTTPClient()
const response = confHTTPClient
.sendRequest(runtime, {
request: {
url: runtime.config.url,
method: "GET",
multiHeaders: {
Authorization: { values: ["Basic {{.apiKey}}"] },
},
},
vaultDonSecrets: [{ key: "apiKey", owner: runtime.config.owner }],
})
.result()
if (!ok(response)) {
throw new Error(`Request failed: ${response.statusCode}`)
}
return (json(response) as APIResult).data
}
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:
bodyString: '{"apiKey": "{{.myApiKey}}", "method": "{{.method}}", "params": []}',
Header template:
multiHeaders: {
"Authorization": { values: ["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:
// These two are equivalent:
// Option 1: hardcoded in the body string
bodyString: '{"method": "eth_blockNumber", "auth": "{{.apiKey}}"}'
// Option 2: using templatePublicValues
bodyString: '{"method": "{{.method}}", "auth": "{{.apiKey}}"}'
templatePublicValues: {
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:
request: {
url: config.url,
method: "POST",
bodyString: '{"method": "{{.rpcMethod}}", "auth": "{{.apiKey}}"}',
templatePublicValues: {
rpcMethod: config.rpcMethod, // dynamic value from config, not a secret
},
},
vaultDonSecrets: [{ key: "apiKey", owner: config.owner }], // 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 backend.
The encrypted response body is structured as nonce || ciphertext || tag.
For a complete example with response encryption, see the Making Confidential Requests guide.