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[] | Vault DON secrets for enclave-only {{.key}} substitution in the request (SecretIdentifier). 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 and Making Confidential Requests. |
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.