Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

### Added
- Added `file` and `azureKeyVaultSecret` token sources, so rotated credentials (e.g., GitHub App installation tokens) are picked up without restarting Sourcebot. [#1705](https://github.com/sourcebot-dev/sourcebot/pull/1705)

### Fixed
- Silenced a false-positive `MaxListenersExceededWarning` logged on every request proxied through an external rewrite. [#1697](https://github.com/sourcebot-dev/sourcebot/pull/1697)

Expand Down
36 changes: 34 additions & 2 deletions docs/docs/configuration/config-file.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,9 @@ The following are settings that can be provided in your config file to modify So

# Tokens

Tokens are used to securely pass secrets to Sourcebot in a config file. They are used in various places, including connections, language model providers, auth providers, etc. Tokens can be passed as either environment variables or Google Cloud secrets:
Tokens are used to securely pass secrets to Sourcebot in a config file. They are used in various places, including connections, language model providers, auth providers, etc. Tokens can be passed as environment variables, files, Google Cloud secrets, or Azure Key Vault secrets.

Environment variables are fixed when the container starts. File, Google Cloud, and Azure Key Vault tokens are read each time Sourcebot resolves them. For connection tokens, this happens on every sync, so you can rotate short-lived credentials (e.g., GitHub App installation tokens) without restarting Sourcebot. Tokens used in `environmentOverrides` are resolved once at startup.

<AccordionGroup>
<Accordion title="Environment Variables">
Expand All @@ -79,11 +81,41 @@ Tokens are used to securely pass secrets to Sourcebot in a config file. They are
}
```
</Accordion>
<Accordion title="Files">
```json
{
"token": {
"file": "/var/run/secrets/sourcebot/token"
}
}
```

The path is resolved inside the Sourcebot container. Use an absolute path. Leading and trailing whitespace is trimmed.

This works with Kubernetes Secret volumes, Docker secrets, the [Secrets Store CSI driver](https://secrets-store-csi-driver.sigs.k8s.io/), or a sidecar that writes refreshed tokens to a shared volume.

<Note>
Kubernetes does not update Secrets mounted with `subPath`. Mount the whole volume if you want rotated values to be picked up.
</Note>
</Accordion>
<Accordion title="Azure Key Vault Secrets">
```json
{
"token": {
"azureKeyVaultSecret": "https://<vault-name>.vault.azure.net/secrets/<secret-name>"
}
}
```

To pin a specific version, append it to the identifier: `https://<vault-name>.vault.azure.net/secrets/<secret-name>/<version>`. If you omit the version, Sourcebot reads the latest version each time.

Sourcebot authenticates with [`DefaultAzureCredential`](https://learn.microsoft.com/en-us/azure/developer/javascript/sdk/authentication/credential-chains#use-defaultazurecredential-for-flexibility). This supports AKS Workload Identity, managed identity, and the `AZURE_CLIENT_ID`, `AZURE_TENANT_ID`, and `AZURE_CLIENT_SECRET` environment variables. The identity needs the **Key Vault Secrets User** role, or a `get` secret access policy, on the vault.
</Accordion>
</AccordionGroup>

# Overriding environment variables from the config

You can override / set environment variables from the config file by using the `environmentOverrides` property. Overrides can be of type `string`, `number`, `boolean`, or a [token](/docs/configuration/config-file#tokens). Tokens are useful when you want to configure a environment variable using a Google Cloud Secret or other supported secret management service.
You can override / set environment variables from the config file by using the `environmentOverrides` property. Overrides can be of type `string`, `number`, `boolean`, or a [token](/docs/configuration/config-file#tokens). Tokens are useful when you want to configure a environment variable using a Google Cloud secret, an Azure Key Vault secret, or other supported secret management service.

<AccordionGroup>
<Accordion title="Token">
Expand Down
52 changes: 52 additions & 0 deletions docs/snippets/schemas/v3/app.schema.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,32 @@
"googleCloudSecret"
],
"additionalProperties": false
},
{
"type": "object",
"properties": {
"file": {
"type": "string",
"description": "The path to a file that contains the token. The file is re-read each time the token is used, so its contents can be rotated without restarting Sourcebot (e.g., a mounted Kubernetes secret)."
}
},
"required": [
"file"
],
"additionalProperties": false
},
{
"type": "object",
"properties": {
"azureKeyVaultSecret": {
"type": "string",
"description": "The identifier of an Azure Key Vault secret. Must be in the format `https://<vault-name>.vault.azure.net/secrets/<secret-name>` or `https://<vault-name>.vault.azure.net/secrets/<secret-name>/<version>`. If the version is omitted, the latest version is used. Authenticates using DefaultAzureCredential. See https://learn.microsoft.com/en-us/azure/key-vault/secrets/about-secrets"
}
},
"required": [
"azureKeyVaultSecret"
],
"additionalProperties": false
}
]
}
Expand Down Expand Up @@ -115,6 +141,32 @@
"googleCloudSecret"
],
"additionalProperties": false
},
{
"type": "object",
"properties": {
"file": {
"type": "string",
"description": "The path to a file that contains the token. The file is re-read each time the token is used, so its contents can be rotated without restarting Sourcebot (e.g., a mounted Kubernetes secret)."
}
},
"required": [
"file"
],
"additionalProperties": false
},
{
"type": "object",
"properties": {
"azureKeyVaultSecret": {
"type": "string",
"description": "The identifier of an Azure Key Vault secret. Must be in the format `https://<vault-name>.vault.azure.net/secrets/<secret-name>` or `https://<vault-name>.vault.azure.net/secrets/<secret-name>/<version>`. If the version is omitted, the latest version is used. Authenticates using DefaultAzureCredential. See https://learn.microsoft.com/en-us/azure/key-vault/secrets/about-secrets"
}
},
"required": [
"azureKeyVaultSecret"
],
"additionalProperties": false
}
]
}
Expand Down
26 changes: 26 additions & 0 deletions docs/snippets/schemas/v3/azuredevops.schema.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,32 @@
"googleCloudSecret"
],
"additionalProperties": false
},
{
"type": "object",
"properties": {
"file": {
"type": "string",
"description": "The path to a file that contains the token. The file is re-read each time the token is used, so its contents can be rotated without restarting Sourcebot (e.g., a mounted Kubernetes secret)."
}
},
"required": [
"file"
],
"additionalProperties": false
},
{
"type": "object",
"properties": {
"azureKeyVaultSecret": {
"type": "string",
"description": "The identifier of an Azure Key Vault secret. Must be in the format `https://<vault-name>.vault.azure.net/secrets/<secret-name>` or `https://<vault-name>.vault.azure.net/secrets/<secret-name>/<version>`. If the version is omitted, the latest version is used. Authenticates using DefaultAzureCredential. See https://learn.microsoft.com/en-us/azure/key-vault/secrets/about-secrets"
}
},
"required": [
"azureKeyVaultSecret"
],
"additionalProperties": false
}
]
},
Expand Down
26 changes: 26 additions & 0 deletions docs/snippets/schemas/v3/bitbucket.schema.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,32 @@
"googleCloudSecret"
],
"additionalProperties": false
},
{
"type": "object",
"properties": {
"file": {
"type": "string",
"description": "The path to a file that contains the token. The file is re-read each time the token is used, so its contents can be rotated without restarting Sourcebot (e.g., a mounted Kubernetes secret)."
}
},
"required": [
"file"
],
"additionalProperties": false
},
{
"type": "object",
"properties": {
"azureKeyVaultSecret": {
"type": "string",
"description": "The identifier of an Azure Key Vault secret. Must be in the format `https://<vault-name>.vault.azure.net/secrets/<secret-name>` or `https://<vault-name>.vault.azure.net/secrets/<secret-name>/<version>`. If the version is omitted, the latest version is used. Authenticates using DefaultAzureCredential. See https://learn.microsoft.com/en-us/azure/key-vault/secrets/about-secrets"
}
},
"required": [
"azureKeyVaultSecret"
],
"additionalProperties": false
}
]
},
Expand Down
130 changes: 130 additions & 0 deletions docs/snippets/schemas/v3/connection.schema.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,32 @@
"googleCloudSecret"
],
"additionalProperties": false
},
{
"type": "object",
"properties": {
"file": {
"type": "string",
"description": "The path to a file that contains the token. The file is re-read each time the token is used, so its contents can be rotated without restarting Sourcebot (e.g., a mounted Kubernetes secret)."
}
},
"required": [
"file"
],
"additionalProperties": false
},
{
"type": "object",
"properties": {
"azureKeyVaultSecret": {
"type": "string",
"description": "The identifier of an Azure Key Vault secret. Must be in the format `https://<vault-name>.vault.azure.net/secrets/<secret-name>` or `https://<vault-name>.vault.azure.net/secrets/<secret-name>/<version>`. If the version is omitted, the latest version is used. Authenticates using DefaultAzureCredential. See https://learn.microsoft.com/en-us/azure/key-vault/secrets/about-secrets"
}
},
"required": [
"azureKeyVaultSecret"
],
"additionalProperties": false
}
]
},
Expand Down Expand Up @@ -258,6 +284,32 @@
"googleCloudSecret"
],
"additionalProperties": false
},
{
"type": "object",
"properties": {
"file": {
"type": "string",
"description": "The path to a file that contains the token. The file is re-read each time the token is used, so its contents can be rotated without restarting Sourcebot (e.g., a mounted Kubernetes secret)."
}
},
"required": [
"file"
],
"additionalProperties": false
},
{
"type": "object",
"properties": {
"azureKeyVaultSecret": {
"type": "string",
"description": "The identifier of an Azure Key Vault secret. Must be in the format `https://<vault-name>.vault.azure.net/secrets/<secret-name>` or `https://<vault-name>.vault.azure.net/secrets/<secret-name>/<version>`. If the version is omitted, the latest version is used. Authenticates using DefaultAzureCredential. See https://learn.microsoft.com/en-us/azure/key-vault/secrets/about-secrets"
}
},
"required": [
"azureKeyVaultSecret"
],
"additionalProperties": false
}
]
},
Expand Down Expand Up @@ -478,6 +530,32 @@
"googleCloudSecret"
],
"additionalProperties": false
},
{
"type": "object",
"properties": {
"file": {
"type": "string",
"description": "The path to a file that contains the token. The file is re-read each time the token is used, so its contents can be rotated without restarting Sourcebot (e.g., a mounted Kubernetes secret)."
}
},
"required": [
"file"
],
"additionalProperties": false
},
{
"type": "object",
"properties": {
"azureKeyVaultSecret": {
"type": "string",
"description": "The identifier of an Azure Key Vault secret. Must be in the format `https://<vault-name>.vault.azure.net/secrets/<secret-name>` or `https://<vault-name>.vault.azure.net/secrets/<secret-name>/<version>`. If the version is omitted, the latest version is used. Authenticates using DefaultAzureCredential. See https://learn.microsoft.com/en-us/azure/key-vault/secrets/about-secrets"
}
},
"required": [
"azureKeyVaultSecret"
],
"additionalProperties": false
}
]
},
Expand Down Expand Up @@ -767,6 +845,32 @@
"googleCloudSecret"
],
"additionalProperties": false
},
{
"type": "object",
"properties": {
"file": {
"type": "string",
"description": "The path to a file that contains the token. The file is re-read each time the token is used, so its contents can be rotated without restarting Sourcebot (e.g., a mounted Kubernetes secret)."
}
},
"required": [
"file"
],
"additionalProperties": false
},
{
"type": "object",
"properties": {
"azureKeyVaultSecret": {
"type": "string",
"description": "The identifier of an Azure Key Vault secret. Must be in the format `https://<vault-name>.vault.azure.net/secrets/<secret-name>` or `https://<vault-name>.vault.azure.net/secrets/<secret-name>/<version>`. If the version is omitted, the latest version is used. Authenticates using DefaultAzureCredential. See https://learn.microsoft.com/en-us/azure/key-vault/secrets/about-secrets"
}
},
"required": [
"azureKeyVaultSecret"
],
"additionalProperties": false
}
]
},
Expand Down Expand Up @@ -949,6 +1053,32 @@
"googleCloudSecret"
],
"additionalProperties": false
},
{
"type": "object",
"properties": {
"file": {
"type": "string",
"description": "The path to a file that contains the token. The file is re-read each time the token is used, so its contents can be rotated without restarting Sourcebot (e.g., a mounted Kubernetes secret)."
}
},
"required": [
"file"
],
"additionalProperties": false
},
{
"type": "object",
"properties": {
"azureKeyVaultSecret": {
"type": "string",
"description": "The identifier of an Azure Key Vault secret. Must be in the format `https://<vault-name>.vault.azure.net/secrets/<secret-name>` or `https://<vault-name>.vault.azure.net/secrets/<secret-name>/<version>`. If the version is omitted, the latest version is used. Authenticates using DefaultAzureCredential. See https://learn.microsoft.com/en-us/azure/key-vault/secrets/about-secrets"
}
},
"required": [
"azureKeyVaultSecret"
],
"additionalProperties": false
}
]
},
Expand Down
26 changes: 26 additions & 0 deletions docs/snippets/schemas/v3/environmentOverrides.schema.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,32 @@
"googleCloudSecret"
],
"additionalProperties": false
},
{
"type": "object",
"properties": {
"file": {
"type": "string",
"description": "The path to a file that contains the token. The file is re-read each time the token is used, so its contents can be rotated without restarting Sourcebot (e.g., a mounted Kubernetes secret)."
}
},
"required": [
"file"
],
"additionalProperties": false
},
{
"type": "object",
"properties": {
"azureKeyVaultSecret": {
"type": "string",
"description": "The identifier of an Azure Key Vault secret. Must be in the format `https://<vault-name>.vault.azure.net/secrets/<secret-name>` or `https://<vault-name>.vault.azure.net/secrets/<secret-name>/<version>`. If the version is omitted, the latest version is used. Authenticates using DefaultAzureCredential. See https://learn.microsoft.com/en-us/azure/key-vault/secrets/about-secrets"
}
},
"required": [
"azureKeyVaultSecret"
],
"additionalProperties": false
}
]
}
Expand Down
Loading