The Secrets component is a connector-level mechanism for declaring sensitive values – such as API keys, access tokens, client secrets, or PII – once and referencing them from authorized parts of the configuration. Each secret is classified by sensitivity and bound to a source that controls how the value is resolved at runtime.
Defining a value as a secret keeps it out of plain-text configuration and restricts where the value can appear in the connector configuration. Secrets can also be used for non-sensitive but reusable values (e.g., region codes or tenant IDs) to avoid duplicating literals across many requests.
Note: If you build your connector through the Connector builder Hub UI, the
secretsobject is generated and updated for you automatically when you add secrets in the UI. You only need to author this section by hand when editing the connector JSON directly.
Registering secrets
Secrets are defined at the connector root level under the secrets property. Each entry in items is a single secret with a unique id, a classification, and a source (for values you provide directly) or a component (for values encrypted with the secret encryption tool – see Encrypting a secret).
Below you can find a template for registering a secret:
{
"secrets": {
"items": [
{
"id": "[unique_secret_id]",
"classification": "[public, secret, or pii]",
"source": "[userInput or static]",
"value": "[input field ID or static value]"
}
]
}
}
The available values for source are:
| Source | Description |
|---|---|
userInput |
The secret is collected from the user during the authentication flow. value is the ID of the user input field that holds it. |
static |
The secret is a plain-text constant stored directly in value. Only allowed for the public and pii classifications – never for secret. |
The classification declares the sensitivity level and controls which sources are allowed:
| Classification | Use for | How the value can be provided |
|---|---|---|
secret |
Highly sensitive data – API keys, access tokens, client secrets, signing keys. | userInput, or encrypted with the secret encryption tool. Cannot use static. |
public |
Non-sensitive but reusable values, such as a region code or tenant ID. | userInput, static, or encrypted with the secret encryption tool. |
pii |
Personally Identifiable Information subject to privacy regulations (GDPR, CCPA, etc.). | userInput, static, or encrypted with the secret encryption tool. |
Encrypting a secret
To store a fixed sensitive value that isn't collected from the user – for example an application-wide API key or a signing key – encrypt it using the secret encryption tool in the Connector builder. This is the only way to encrypt a value in the Connector builder.
When you encrypt a value with the tool:
- The value is stored in the Connector builder vault.
- The matching entry in the
secretsobject is created for you automatically, using theconnector_builder_vaultcomponent to resolve the value from the vault.
You don't author encrypted values by hand, and there is no encrypted source to set. The generated entry uses a component instead of a source – the componentId points at the vault, and value is the vault lookup key:
{
"secrets": {
"items": [
{
"id": "sec_app_api_key",
"classification": "secret",
"component": {
"override": {
"componentId": "connector_builder_vault"
}
},
"value": "sec_app_api_key"
}
]
}
}
Once created, a vault-backed secret is referenced exactly like any other secret.
Note: A secret entry specifies either a
sourceor acomponent, never both. Values you provide directly use asource(userInputorstatic); values you encrypt with the tool use the vaultcomponent, which is added for you.
Referencing a secret
Adding a secret to items does not inject it anywhere – each consumer must reference it by id. There are two ways to reference a secret, and each is available only in specific places: not every field supports both forms.
As a placeholder: {{secrets.<id>}}
Use the {{secrets.<id>}} placeholder inside request fields. It is restricted to the locations below; using it anywhere else is rejected at validation time.
| Location | Notes |
|---|---|
request.url |
Any request URL, anywhere a request object appears. |
request.headers[*] |
Header names and values. |
request.parameters[*] |
Query parameter names and values. |
request.body.content |
Raw request body. |
request.body.formData[*] |
Form data fields. |
request.async.<phase>.{url, headers, parameters, body.content, body.formData} |
The same fields inside the async phases init, poll, postPoll, and delete. |
signers.items[*].payload |
Inside a signer's payload template. See Request signers. |
Below you can find an example of referencing a secret in a request header:
{
"url": "https://api.example.com/data",
"headers": [
{ "name": "Authorization", "value": "Bearer {{secrets.api_key}}" }
]
}
As a value source: source: "secret"
Some fields take their value from a source object rather than a placeholder. Where the field supports it, set source to secret and value to the secret's id:
{
"source": "secret",
"value": "app_secret"
}
This form is accepted only by the fields that have opted in. The current list:
| Location | Notes |
|---|---|
signers.items[*].algorithm.secret |
HMAC/RSA signing key. Accepts only source: "secret". |
authentication.jwt.secret |
JWT signing key (PEM-encoded private key). |
authentication.jwt.keyId |
JWT kid header claim. |
authentication.jwt.passphrase |
Passphrase for an encrypted private key. |
authentication.jwt.claims[*].value |
A JWT claim value, for sensitive claims. |
authentication.oauth2.clientId / clientSecret |
OAuth2 application credentials. |
authentication.singleStepOAuth2.clientId / clientSecret |
Single-step OAuth2 application credentials. |
authentication.oauth1.consumerKey / consumerSecret |
OAuth1 consumer credentials. |
Choosing between the two forms
- Use the
{{secrets.<id>}}placeholder when the secret goes into a request (URL, header, parameter, or body) or a signer payload. - Use the
source: "secret"value source when the secret goes into an authentication or signer field that resolves its value from a source object – JWT keys, OAuth/OAuth1 credentials, or the signer algorithm key.
Some of those fields – the signer algorithm key and the OAuth credential objects – accept only the source: "secret" form and never a placeholder.
Examples
Storing a user-provided value as a secret
The connector collects an API key from the user and sends it in a request header. The key is collected as a user input, registered as a secret, and referenced with the {{secrets.api_key}} placeholder.
First, collect the key as a user input. Use the password type so the value is masked in the user interface:
{
"authentication": {
"type": "user_input",
"userInputs": [
{
"id": "api_key",
"label": "API key",
"type": "password"
}
]
}
}
Register it as a secret, with source: "userInput" and value set to the id of the input field:
{
"secrets": {
"items": [
{
"id": "api_key",
"classification": "secret",
"source": "userInput",
"value": "api_key"
}
]
}
}
Reference it in a request:
{
"url": "https://api.example.com/v1/reports",
"headers": [
{ "name": "Authorization", "value": "Bearer {{secrets.api_key}}" }
]
}
At request time, {{secrets.api_key}} resolves to the value the user entered during authentication.
Using a value encrypted with the secret encryption tool
The connector uses a single application-wide API key that is the same for all users. Encrypt it once with the secret encryption tool; the vault-backed entry is added to the secrets object for you automatically:
{
"secrets": {
"items": [
{
"id": "sec_app_api_key",
"classification": "secret",
"component": {
"override": {
"componentId": "connector_builder_vault"
}
},
"value": "sec_app_api_key"
}
]
}
}
Reference it exactly like any other secret:
{
"url": "https://api.example.com/v1/reports",
"headers": [
{ "name": "X-Api-Key", "value": "{{secrets.sec_app_api_key}}" }
]
}
Duplicating a connector
When you duplicate a connector, its secrets are copied to the new connector for you. You do not need to register or encrypt them again.
Both kinds of secret are carried across:
| Secret | What happens |
|---|---|
| Stored in the Connector builder vault | The value is copied into the new connector's own vault entry, under the same id. Every {{secrets.<id>}} reference in the copied configuration keeps working. |
source: "encrypted" |
The value is decrypted and encrypted again with the new connector's key, in place in the copied configuration. Nothing else in the configuration changes. |
Every connector has its own encryption key. This is why encrypted values cannot simply be copied as they are: a value encrypted for one connector cannot be read by another. The decryption and the new encryption both happen inside the Supermetrics backend, so the plain value never leaves it.
Duplicating a connector stays inside your team. The copy belongs to the same team as the original, and the same people can access both.
Note: If copying a secret fails, the new connector is still created, but it may be missing some of its secrets. You will see this the first time you save its configuration, when a missing secret is reported. Register the missing secret again on the new connector to fix it.