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.

Quick reference

MethodDescription
sendRequestMakes 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
requestHTTPRequest | HTTPRequestJsonThe HTTP request to execute inside the enclave. See HTTPRequest.
vaultDonSecretsSecretIdentifier[] | 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
urlstringThe URL of the API endpoint.
methodstringThe HTTP method (e.g., "GET", "POST").
bodyStringstring (optional)The request body as a string template. Use this for secret injection with {{.secretName}} placeholders.
bodyBytesUint8Array | 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.
customRootCaCertPemUint8Array | string (optional)Optional custom root CA certificate (PEM format) for verifying the external server's TLS certificate.
timeoutDuration | DurationJson (optional)Optional request timeout (e.g., "5s").
encryptOutputboolean (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
statusCodenumberThe HTTP status code.
bodyUint8Array | 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.

FieldTypeDescription
keystringThe logical name of the secret. Must match the template placeholder (e.g., "myApiKey" matches {{.myApiKey}}).
namespacestringThe secret namespace.
ownerstring (optional)Optional. The owner address for the secret.

HeaderValues / HeaderValuesJson

Represents multiple values for a single HTTP header key.

Field
Type
Description
valuesstring[]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: The Runtime instance from your trigger handler.
  • input: A ConfidentialHTTPRequest or ConfidentialHTTPRequestJson object 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.

encryptOutputSecret key providedBehavior
false (default)Response returned unencrypted.
truesan_marino_aes_gcm_encryption_key in vaultDonSecretsResponse AES-GCM encrypted with your symmetric key.
trueNo key providedResponse 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.

Get the latest Chainlink content straight to your inbox.