
## Install on Kubernetes - Amazon SageMaker

URL: https://docs.atlan.com/product/connections/self-deployed-runtime/how-tos/install-on-kubernetes
**Connector:** Amazon SageMaker (ai)

> Install an App on Kubernetes using Helm charts, Docker images, and specific configuration

:::info **Did you know?** 
SDR requires additional enablement and licensing. Contact your Atlan representative for details.
:::

:::warning Use the guided install wizard instead
**New Self-Deployed Runtime setups are encouraged to use the [guided install wizard](https://docs.atlan.com/product/connections/self-deployed-runtime/how-tos/install-guided).** It assembles a complete guide tailored to your lifecycle mode, platform, and image procurement on a single page—and it's where new setup options (for example, HTTP proxy and custom CA trust) are documented going forward.

This page is kept for existing users who already reference it and may not include the latest steps.
:::

<h2 id="prerequisites">Prerequisites</h2>

Before you begin, make sure you have:

* `kubectl` installed and configured with administrative access to your target Kubernetes cluster
* Helm version 3.0 or later installed on your deployment machine
* A [Docker Hub Personal Access Token (PAT)](https://start.1password.com/open/i?a=WAVUZSKJO5GMNMVBYWAWECXIUE&v=ouvp3xf5334cxoamyiipzjlewy&i=p76avgzmkkcbftldcuvr5jcof4&h=atlanhq.1password.com) from Atlan
* App-specific helm chart name: `{{deploymentValues.helmChartName}}` 
* Object storage: AWS S3, Google Cloud Storage, or Azure Blob Storage with read/write permissions
* Secret store access: AWS Secret Manager, Azure Key Vault, GCP Secret Manager, HashiCorp Vault, or Kubernetes Secrets with read permissions

:::warning For security reasons, the Docker Hub PAT Token is regenerated on a periodic basis. 
In case the token is embedded in automation scripts or CI/CD pipelines, those jobs may fail. 
Contact your Atlan representative for the latest token.
:::

<h2 id="download-required-files">Download required files</h2>

<h3 id="download-helm-chart">Download Helm chart</h3>

Download the Helm chart for the app:

```bash
helm pull oci://registry-1.docker.io/atlanhq/{{deploymentValues.helmChartName}} --untar
```

This unpacks the chart's `Chart.yaml`, `templates/`, and a default `values.yaml` into `./{{deploymentValues.helmChartName}}/`. You'll replace this default `values.yaml` with your Marketplace copy in the next step.

<h3 id="download-values-yaml">Download values.yaml</h3>

Atlan generates the helm `values.yaml` for your runtime directly from the Marketplace UI, including the OAuth client credentials your runtime uses to authenticate to your tenant.

1. Sign in to your Atlan tenant as an administrator, open **Connector** > **Marketplace**, select the app you want to deploy, and click **Download config for Self-Deployed Runtime** in the right-hand sidebar.

2. In the dialog, keep **New deployment** selected (this mints the OAuth client and full config for a fresh runtime), choose **Kubernetes (Helm)** as the deployment target, and enter a **Deployment name**: a short identifier (lowercase letters, digits, and dashes) that identifies this runtime; the agent in **Workflows > Agent** is named `<app_name>-<deployment_name>`.

3. Click **Generate**. Atlan mints a dedicated OAuth client and produces a `values.yaml` file with:
 - `global.atlanBaseUrl`, `global.clientId`, and `global.clientSecret` already filled in.
 - `image.repository`, `image.tag`, and `name` pinned to the active version for your tenant.
 - `objectstore` and `secretstore` placeholders for you to configure below.

<h3 id="replace-chart-values">Replace chart values.yaml</h3>

Replace the default `values.yaml` inside the unpacked chart with the `values.yaml` you downloaded from the Marketplace.

From this point on, all edits to `values.yaml` must be made inside `./{{deploymentValues.helmChartName}}/`.

<h2 id="modify-values-yaml">Modify values.yaml</h2>

### Object storage

Self-Deployed Runtime needs a store for reading or writing files. Configure the object storage that matches your environment:

:::tip Don't see your preferred object store?
If your preferred object store isn't listed here, [reach out to Atlan support](https://docs.atlan.com/support/submit-request). Support for additional object stores may be available.
:::

<Tabs>
<TabItem value="aws-s3" label="AWS S3" default>

**Required permissions:**

Apply object-level actions to `arn:aws:s3:::BUCKET/*` and the list action to `arn:aws:s3:::BUCKET` in separate IAM statement entries.

| IAM action | Operations covered |
|---|---|
| `s3:GetObject` | GetObject (full and byte-range), HeadObject |
| `s3:PutObject` | PutObject, CreateMultipartUpload, UploadPart, CompleteMultipartUpload |
| `s3:AbortMultipartUpload` | Abort in-flight multipart upload on error (required for streaming write error paths) |
| `s3:DeleteObject` | DeleteObject and DeleteObjects (bulk batch—same IAM action) |
| `s3:ListBucket` | ListObjectsV2—bucket-level permission, not object-level |

```json
{
 "Version": "2012-10-17",
 "Statement": [
 {
 "Effect": "Allow",
 "Action": [
 "s3:GetObject",
 "s3:PutObject",
 "s3:AbortMultipartUpload",
 "s3:DeleteObject"
 ],
 "Resource": "arn:aws:s3:::YOUR-BUCKET/*"
 },
 {
 "Effect": "Allow",
 "Action": "s3:ListBucket",
 "Resource": "arn:aws:s3:::YOUR-BUCKET"
 }
 ]
}
```

**AssumeRole**: when using `assumeRoleArn`, the caller identity additionally needs `sts:AssumeRole` on the target role ARN. The role itself holds the bucket policy described earlier.

**Configure:**

 1. Locate the `objectstore` attribute in `values.yaml`.
 2. Add AWS S3 configuration. For more information, see [AWS S3 Binding Spec](https://docs.dapr.io/reference/components-reference/supported-bindings/s3/).

 ```yaml
 objectstore:
 enabled: true
 spec:
 type: bindings.aws.s3
 version: v1
 metadata:
 - name: accessKey #optional, leave this empty for iam authentication
 value: ""
 - name: secretKey #optional, leave this empty for iam authentication
 value: ""
 - name: bucket #required, name of the bucket where application can write
 value: "<bucket-name>"
 - name: region #required, region of the bucket where application can write
 value: "<bucket-region>"
 - name: forcePathStyle
 value: "true"
 ```

</TabItem>
<TabItem value="gcp-storage" label="Google Cloud Storage">

**Required permissions:**

| IAM permission | Operations covered |
|---|---|
| `storage.objects.get` | GetObject (full and byte-range), object metadata / HeadObject equivalent |
| `storage.objects.create` | PutObject, resumable / streaming write |
| `storage.objects.delete` | DeleteObject (GCS has no native bulk-delete API—`delete_prefix` issues parallel single-object deletes) |
| `storage.objects.list` | ListObjects |

No `storage.buckets.*` permissions are needed. The smallest predefined role that covers all four is **`roles/storage.objectAdmin`** scoped to the bucket. Alternatively, create a custom role with exactly these four permissions.

**Configure:**

 1. Locate the `objectstore` attribute in `values.yaml`.
 2. Add Google Cloud Storage configuration. For more information, see [GCP Storage Bucket binding spec](https://docs.dapr.io/reference/components-reference/supported-bindings/gcpbucket/)

 ```yaml
 objectstore:
 enabled: true
 spec:
 type: bindings.gcp.bucket
 version: v1
 metadata:
 - name: bucket
 value: "your-gcs-bucket-name"
 - name: type
 value: "service_account"
 - name: project_id
 value: "your-gcp-project-id"
 ```

</TabItem>
<TabItem value="azure-blob" label="Azure Blob Storage">

**Required permissions:**

**RBAC**—assign at container or storage-account scope:

| RBAC action | Operations covered |
|---|---|
| `Microsoft.Storage/storageAccounts/blobServices/containers/blobs/read` | GetBlob, GetBlobProperties (HEAD), ListBlobs, byte-range GET |
| `Microsoft.Storage/storageAccounts/blobServices/containers/blobs/write` | PutBlob, PutBlock + PutBlockList (streaming / block write) |
| `Microsoft.Storage/storageAccounts/blobServices/containers/blobs/delete` | DeleteBlob, BlobBatch delete (bulk—up to 256 keys per request) |

The smallest predefined role covering all three is **`Storage Blob Data Contributor`**. `Storage Blob Data Owner` is a superset and is only needed if you additionally require POSIX ACL management on ADLS Gen2.

**SAS token**—minimum permissions at container scope: `r` (read) + `w` (write) + `d` (delete) + `l` (list), that is a container-scoped SAS with **`rwdl`**.

**ADLS Gen2 with POSIX ACLs**: if the storage account has hierarchical namespace enabled and you use ACL-based access control instead of RBAC, the principal needs Execute (`X`) on every parent directory and Read / Write / Delete on the objects in scope. RBAC (`Storage Blob Data Contributor`) is simpler and is recommended unless you have a specific ACL requirement.

**Configure:**

 1. Locate the `objectstore` attribute in `values.yaml`.
 2. Add Azure Blob Storage configuration. For more information, see [Azure Blob Storage binding spec](https://docs.dapr.io/reference/components-reference/supported-bindings/blobstorage/)

 ```yaml
 objectstore:
 enabled: true
 spec:
 type: bindings.azure.blobstorage
 version: v1
 metadata:
 - name: accountName
 value: "your-storage-account-name"
 - name: accountKey
 value: "your-storage-account-key"
 - name: containerName
 value: "your-container-name"
 ```

</TabItem>
</Tabs>

### Secret storage

Self-Deployed Runtime fetches secrets from a secret store to connect to the source systems. The secret store references are used to configure the workflow. Configure the secret store that aligns with your security infrastructure:

:::info Did you know?
Dapr supports additional secret stores which aren't mentioned here. For more information, see [Dapr secret store documentation](https://docs.dapr.io/reference/components-reference/supported-secret-stores/) for other configurations.
:::

:::warning Secret content format and naming
When storing credentials, follow the [secret naming and format requirements](https://docs.atlan.com/product/connections/self-deployed-runtime/how-tos/configure-workflow-execution#secret-content-format).
:::

<Tabs>
<TabItem value="aws-secret-manager" label="AWS Secret Manager" default>
 
 1. Locate the `secretstore` attribute in `values.yaml`.
 2. Add AWS Secret Manager configuration. For more information, see [AWS Secrets Manager](https://docs.dapr.io/reference/components-reference/supported-secret-stores/aws-secret-manager/)

 ```yaml
 secretstore:
 enabled: true
 spec:
 type: secretstores.aws.secretmanager
 version: v1
 metadata:
 - name: region # required, region in which secret is hosted
 value: <secret-region>
 # Needed if IAM authentication is not used
 - name: accessKey
 value: ""
 - name: secretKey
 value: ""
 ```

If you are using IAM role / IRSA authentication, leave `accessKey` and `secretKey` empty.

If you are using an IAM user instead, set:
- `accessKey` to the IAM user's access key ID
- `secretKey` to the IAM user's secret access key

That IAM user must have permission to read the target secret from AWS Secrets Manager:

```json
{
 "Version": "2012-10-17",
 "Statement": [
 {
 "Effect": "Allow",
 "Action": [
 "secretsmanager:GetSecretValue",
 "secretsmanager:DescribeSecret"
 ],
 "Resource": "arn:aws:secretsmanager:<region>:<account-id>:secret:<secret-name>*"
 }
 ]
}
```

:::note
Include the trailing `*` in the secret ARN. AWS appends a random suffix to secret names in the ARN, so omitting it can cause access failures.
:::

</TabItem>
<TabItem value="azure-key-vault" label="Azure Key Vault">

 1. Locate the `secretstore` attribute in `values.yaml`.
 2. Add Azure Key Vault configuration. For more information, see [Azure Key Vault secret store](https://docs.dapr.io/reference/components-reference/supported-secret-stores/azure-keyvault/)

 ```yaml
 secretstore:
 enabled: true
 spec:
 type: secretstores.azure.keyvault
 version: v1
 metadata:
 - name: vaultName
 value: "<your-keyvault-name>"
 - name: azureTenantId
 value: "<your-tenant-id>"
 - name: azureClientId
 value: "<your-client-id>"
 - name: azureClientSecret
 value: "<your-client-secret>"
 - name: azureEnvironment
 value: "AZUREPUBLICCLOUD" # Optional: AZUREPUBLICCLOUD, AZURECHINACLOUD, AZUREUSGOVERNMENTCLOUD, AZUREGERMANCLOUD
 ```
 Azure Key Vault supports multiple authentication methods:
 - **Client Secret**: Use `azureClientSecret` with tenant ID and client ID
 - **Certificate**: Use `azureCertificateFile` instead of client secret
 - **Managed Identity**: Omit authentication fields and use Azure managed identity

 For detailed authentication setup, see the [Authenticating to Azure](https://docs.dapr.io/developing-applications/integrations/azure/azure-authentication/authenticating-azure/) documentation.

</TabItem>
<TabItem value="gcp-secret-manager" label="GCP Secret Manager">

1. Locate the `secretstore` attribute in `values.yaml`.
2. Add Google Cloud Secret Manager configuration. For more information, see [GCP Secret Manager](https://docs.dapr.io/reference/components-reference/supported-secret-stores/gcp-secret-manager/)

 The GCP service account used in this configuration must have the `Secret Manager Secret Accessor` role (`roles/secretmanager.secretAccessor`) on the project where your secrets are stored. The metadata values below come from the service account's JSON key file.

 ```yaml
 secretstore:
 enabled: true
 spec:
 type: secretstores.gcp.secretmanager
 version: v1
 metadata:
 - name: type
 value: "service_account"
 - name: project_id
 value: "<project-id>"
 - name: private_key_id
 value: "<private-key-id>"
 - name: private_key
 value: "<private-key>"
 - name: client_email
 value: "<client-email>"
 - name: client_id
 value: "<client-id>"
 - name: auth_uri
 value: "https://accounts.google.com/o/oauth2/auth"
 - name: token_uri
 value: "https://oauth2.googleapis.com/token"
 - name: auth_provider_x509_cert_url
 value: "https://www.googleapis.com/oauth2/v1/certs"
 - name: client_x509_cert_url
 value: "https://www.googleapis.com/robot/v1/metadata/x509/<client-email>"
 ```

</TabItem>
<TabItem value="hashicorp-vault" label="HashiCorp Vault">

1. Locate the `secretstore` attribute in `values.yaml`.
2. Add HashiCorp Vault configuration. For more information, see [HashiCorp Vault](https://docs.dapr.io/reference/components-reference/supported-secret-stores/hashicorp-vault/)

 ```yaml
 secretstore:
 enabled: true
 spec:
 type: secretstores.hashicorp.vault
 version: v1
 metadata:
 - name: vaultAddr
 value: "[vault_address]" # Optional. Default: "https://127.0.0.1:8200"
 - name: caCert # Optional. This or caPath or caPem
 value: "[ca_cert]"
 - name: caPath # Optional. This or CaCert or caPem
 value: "[path_to_ca_cert_file]"
 - name: caPem # Optional. This or CaCert or CaPath
 value: "[encoded_ca_cert_pem]"
 - name: skipVerify # Optional. Default: false
 value: "[skip_tls_verification]"
 - name: tlsServerName # Optional.
 value: "[tls_config_server_name]"
 - name: vaultTokenMountPath # Required if vaultToken not provided. Path to token file.
 value: "[path_to_file_containing_token]"
 - name: vaultToken # Required if vaultTokenMountPath not provided. Token value.
 value: "[vault_token]"
 - name: vaultKVPrefix # Optional. Default: "dapr"
 value: "[vault_prefix]"
 - name: vaultKVUsePrefix # Optional. default: "true"
 value: "[true/false]"
 - name: enginePath # Optional. default: "secret"
 value: "secret"
 - name: vaultValueType # Optional. default: "map"
 value: "map"
 ```

</TabItem>
<TabItem value="kubernetes-secrets" label="Kubernetes Secrets">

1. Locate the `secretstore` attribute in `values.yaml`.
2. Add Kubernetes native secret storage. For more information, see [Kubernetes secrets](https://docs.dapr.io/reference/components-reference/supported-secret-stores/kubernetes-secret-store/)

 ```yaml
 secretstore:
 enabled: true
 spec:
 type: secretstores.kubernetes
 version: v1
 metadata:
 - name: defaultNamespace
 value: "default" # Optional: Default namespace to retrieve secrets from
 - name: kubeconfigPath
 value: "/path/to/kubeconfig" # Optional: Path to kubeconfig file
 ```
 When Dapr is deployed to a Kubernetes cluster, a secret store with the name `kubernetes` is automatically provisioned. You can use this native Kubernetes secret store with no need to create, deploy or maintain a component configuration file.

</TabItem>
<TabItem value="environment-variable-based" label="Environment Variables">

1. Locate the `secretstore` attribute in `values.yaml`.
2. Add Local environment variables as the spec. For more information, see [Local Environment Variables](https://docs.dapr.io/reference/components-reference/supported-secret-stores/envvar-secret-store/)

 ```yaml
 secretstore:
 enabled: true
 spec:
 type: secretstores.local.env
 version: v1
 ```

</TabItem>
</Tabs>

### Image source

Choose how the cluster pulls the app image. Most installs use Atlan's Docker Hub directly; mirror to a private registry if your organization requires it.

<Tabs>
<TabItem value="docker-hub" label="Public Docker Hub" default>

The chart pulls the app image from Atlan's Docker Hub at runtime. The pod needs a Kubernetes secret containing your Docker Hub PAT to authenticate:

```bash
kubectl create secret docker-registry atlan-docker-secret \
 --docker-server=docker.io \
 --docker-username=YOUR_USERNAME \
 --docker-password=YOUR_PAT_TOKEN \
 -n <namespace>
```

- Replace `YOUR_USERNAME` with the Docker Hub username provided by Atlan.
- Replace `YOUR_PAT_TOKEN` with the Personal Access Token (PAT) provided by Atlan.
- Replace `<namespace>` with the namespace you need to install the chart into. The secret and the release must live in the same namespace, or the pod fails with `ImagePullBackOff`.

The downloaded `values.yaml` already references this secret under `imagePullSecrets`. If you use a different secret name, update that field in the file.

</TabItem>
<TabItem value="private-registry" label="Private image repo">

Mirror the Atlan image to your enterprise registry and update `values.yaml` to point at it.

1. Authenticate with Docker Hub using the PAT from Atlan, then pull the source image. The image and tag come from `image.repository` and `image.tag` in the downloaded `values.yaml`:

 ```bash
 docker login -u atlanhq
 # When prompted for password, enter the PAT provided by Atlan
 docker pull <image.repository>:<image.tag>
 ```

2. Push the image to your enterprise's registry. Note down the new repository name and image tag.

3. Update `image.repository` and `image.tag` in `values.yaml` with the new values.

4. If your private registry requires authentication, create an image-pull secret in the target namespace and set `imagePullSecrets` in `values.yaml` to its name.

</TabItem>
</Tabs>

<h2 id="deploy-app">Deploy app</h2>

Follow these steps to deploy the secure app:

* Install the helm chart. The chart directory now carries your edited `values.yaml`, so no `-f` flag is needed:

 ```bash
 helm install {{deploymentValues.helmChartName}}-release ./{{deploymentValues.helmChartName}} -n <namespace>
 ```

 - Replace `<namespace>` with your target Kubernetes namespace.
 - The helm chart name `{{deploymentValues.helmChartName}}` is automatically used from your selected app.

The deployment process typically takes a few minutes to complete depending on factors like Kubernetes cluster resource availability, private image repository download time etc.

<h2 id="verify-app">Verify app</h2>

Follow these steps to verify deployment:

### Verify deployment status on cluster

1. Check pod status:

 ```bash
 kubectl get pods -n <namespace>
 ```

 The output appears similar to:

 ```
 NAME READY STATUS RESTARTS AGE
 <helm-chart-name>-release-<helm-chart-name>-5dff95cd85-cvk5z 1/1 Running 0 2m
 ```
 
 Replace `<helm-chart-name>` with your app's helm chart name (shown in the prerequisites section earlier in this guide).

 The pod status shows `Running` with `1/1` ready containers.

2. Verify logs for the running pod
 
 ```bash
 kubectl logs -n <namespace> -l app.kubernetes.io/name={{deploymentValues.helmChartName}} --tail=50 -f
 ```
 **Example application logs**: Look for these key log messages that confirm successful deployment:

 * `Uvicorn running on http://0.0.0.0:8000` - Web server started
 * `Workflow engine initialized` - Workflow processing ready
 * `dapr initialized. Status: Running` - Dapr runtime active
 * `Starting worker with task queue: atlan-<package-name>-DEPLOYMENT_NAME` - Worker process started (replace `<package-name>` with your app's package name)
 * `GET /server/ready 200` - Health check endpoint responding

### Verify registration via Atlan UI

Once the App is successfully deployed, it communicates to the Atlan tenant and registers itself. Verify App registration is successful in Atlan:

1. In the same Atlan tenant, navigate to **Workflows** > **Agent**.
2. Look for an entry named `<app_name>-<deployment_name>`, where `<app_name>` matches your selected app (for example, "Oracle" or "Microsoft SQL Server") and `<deployment_name>` is the deployment name you entered when generating the config.
3. Confirm the agent status displays as **Active**.

Agent registration and status takes a couple of minutes to reflect in the Atlan UI.

<h2 id="next-steps">Next steps</h2>

* [Configure workflow execution](https://docs.atlan.com/product/connections/self-deployed-runtime/how-tos/configure-workflow-execution): Set up workflow execution with secret retrieval for your Self-deployed Runtime

---

## Install on Kubernetes - Anaplan

URL: https://docs.atlan.com/product/connections/self-deployed-runtime/how-tos/install-on-kubernetes
**Connector:** Anaplan (business-intelligence)

> Install an App on Kubernetes using Helm charts, Docker images, and specific configuration

:::info **Did you know?** 
SDR requires additional enablement and licensing. Contact your Atlan representative for details.
:::

:::warning Use the guided install wizard instead
**New Self-Deployed Runtime setups are encouraged to use the [guided install wizard](https://docs.atlan.com/product/connections/self-deployed-runtime/how-tos/install-guided).** It assembles a complete guide tailored to your lifecycle mode, platform, and image procurement on a single page—and it's where new setup options (for example, HTTP proxy and custom CA trust) are documented going forward.

This page is kept for existing users who already reference it and may not include the latest steps.
:::

<h2 id="prerequisites">Prerequisites</h2>

Before you begin, make sure you have:

* `kubectl` installed and configured with administrative access to your target Kubernetes cluster
* Helm version 3.0 or later installed on your deployment machine
* A [Docker Hub Personal Access Token (PAT)](https://start.1password.com/open/i?a=WAVUZSKJO5GMNMVBYWAWECXIUE&v=ouvp3xf5334cxoamyiipzjlewy&i=p76avgzmkkcbftldcuvr5jcof4&h=atlanhq.1password.com) from Atlan
* App-specific helm chart name: `{{deploymentValues.helmChartName}}` 
* Object storage: AWS S3, Google Cloud Storage, or Azure Blob Storage with read/write permissions
* Secret store access: AWS Secret Manager, Azure Key Vault, GCP Secret Manager, HashiCorp Vault, or Kubernetes Secrets with read permissions

:::warning For security reasons, the Docker Hub PAT Token is regenerated on a periodic basis. 
In case the token is embedded in automation scripts or CI/CD pipelines, those jobs may fail. 
Contact your Atlan representative for the latest token.
:::

<h2 id="download-required-files">Download required files</h2>

<h3 id="download-helm-chart">Download Helm chart</h3>

Download the Helm chart for the app:

```bash
helm pull oci://registry-1.docker.io/atlanhq/{{deploymentValues.helmChartName}} --untar
```

This unpacks the chart's `Chart.yaml`, `templates/`, and a default `values.yaml` into `./{{deploymentValues.helmChartName}}/`. You'll replace this default `values.yaml` with your Marketplace copy in the next step.

<h3 id="download-values-yaml">Download values.yaml</h3>

Atlan generates the helm `values.yaml` for your runtime directly from the Marketplace UI, including the OAuth client credentials your runtime uses to authenticate to your tenant.

1. Sign in to your Atlan tenant as an administrator, open **Connector** > **Marketplace**, select the app you want to deploy, and click **Download config for Self-Deployed Runtime** in the right-hand sidebar.

2. In the dialog, keep **New deployment** selected (this mints the OAuth client and full config for a fresh runtime), choose **Kubernetes (Helm)** as the deployment target, and enter a **Deployment name**: a short identifier (lowercase letters, digits, and dashes) that identifies this runtime; the agent in **Workflows > Agent** is named `<app_name>-<deployment_name>`.

3. Click **Generate**. Atlan mints a dedicated OAuth client and produces a `values.yaml` file with:
 - `global.atlanBaseUrl`, `global.clientId`, and `global.clientSecret` already filled in.
 - `image.repository`, `image.tag`, and `name` pinned to the active version for your tenant.
 - `objectstore` and `secretstore` placeholders for you to configure below.

<h3 id="replace-chart-values">Replace chart values.yaml</h3>

Replace the default `values.yaml` inside the unpacked chart with the `values.yaml` you downloaded from the Marketplace.

From this point on, all edits to `values.yaml` must be made inside `./{{deploymentValues.helmChartName}}/`.

<h2 id="modify-values-yaml">Modify values.yaml</h2>

### Object storage

Self-Deployed Runtime needs a store for reading or writing files. Configure the object storage that matches your environment:

:::tip Don't see your preferred object store?
If your preferred object store isn't listed here, [reach out to Atlan support](https://docs.atlan.com/support/submit-request). Support for additional object stores may be available.
:::

<Tabs>
<TabItem value="aws-s3" label="AWS S3" default>

**Required permissions:**

Apply object-level actions to `arn:aws:s3:::BUCKET/*` and the list action to `arn:aws:s3:::BUCKET` in separate IAM statement entries.

| IAM action | Operations covered |
|---|---|
| `s3:GetObject` | GetObject (full and byte-range), HeadObject |
| `s3:PutObject` | PutObject, CreateMultipartUpload, UploadPart, CompleteMultipartUpload |
| `s3:AbortMultipartUpload` | Abort in-flight multipart upload on error (required for streaming write error paths) |
| `s3:DeleteObject` | DeleteObject and DeleteObjects (bulk batch—same IAM action) |
| `s3:ListBucket` | ListObjectsV2—bucket-level permission, not object-level |

```json
{
 "Version": "2012-10-17",
 "Statement": [
 {
 "Effect": "Allow",
 "Action": [
 "s3:GetObject",
 "s3:PutObject",
 "s3:AbortMultipartUpload",
 "s3:DeleteObject"
 ],
 "Resource": "arn:aws:s3:::YOUR-BUCKET/*"
 },
 {
 "Effect": "Allow",
 "Action": "s3:ListBucket",
 "Resource": "arn:aws:s3:::YOUR-BUCKET"
 }
 ]
}
```

**AssumeRole**: when using `assumeRoleArn`, the caller identity additionally needs `sts:AssumeRole` on the target role ARN. The role itself holds the bucket policy described earlier.

**Configure:**

 1. Locate the `objectstore` attribute in `values.yaml`.
 2. Add AWS S3 configuration. For more information, see [AWS S3 Binding Spec](https://docs.dapr.io/reference/components-reference/supported-bindings/s3/).

 ```yaml
 objectstore:
 enabled: true
 spec:
 type: bindings.aws.s3
 version: v1
 metadata:
 - name: accessKey #optional, leave this empty for iam authentication
 value: ""
 - name: secretKey #optional, leave this empty for iam authentication
 value: ""
 - name: bucket #required, name of the bucket where application can write
 value: "<bucket-name>"
 - name: region #required, region of the bucket where application can write
 value: "<bucket-region>"
 - name: forcePathStyle
 value: "true"
 ```

</TabItem>
<TabItem value="gcp-storage" label="Google Cloud Storage">

**Required permissions:**

| IAM permission | Operations covered |
|---|---|
| `storage.objects.get` | GetObject (full and byte-range), object metadata / HeadObject equivalent |
| `storage.objects.create` | PutObject, resumable / streaming write |
| `storage.objects.delete` | DeleteObject (GCS has no native bulk-delete API—`delete_prefix` issues parallel single-object deletes) |
| `storage.objects.list` | ListObjects |

No `storage.buckets.*` permissions are needed. The smallest predefined role that covers all four is **`roles/storage.objectAdmin`** scoped to the bucket. Alternatively, create a custom role with exactly these four permissions.

**Configure:**

 1. Locate the `objectstore` attribute in `values.yaml`.
 2. Add Google Cloud Storage configuration. For more information, see [GCP Storage Bucket binding spec](https://docs.dapr.io/reference/components-reference/supported-bindings/gcpbucket/)

 ```yaml
 objectstore:
 enabled: true
 spec:
 type: bindings.gcp.bucket
 version: v1
 metadata:
 - name: bucket
 value: "your-gcs-bucket-name"
 - name: type
 value: "service_account"
 - name: project_id
 value: "your-gcp-project-id"
 ```

</TabItem>
<TabItem value="azure-blob" label="Azure Blob Storage">

**Required permissions:**

**RBAC**—assign at container or storage-account scope:

| RBAC action | Operations covered |
|---|---|
| `Microsoft.Storage/storageAccounts/blobServices/containers/blobs/read` | GetBlob, GetBlobProperties (HEAD), ListBlobs, byte-range GET |
| `Microsoft.Storage/storageAccounts/blobServices/containers/blobs/write` | PutBlob, PutBlock + PutBlockList (streaming / block write) |
| `Microsoft.Storage/storageAccounts/blobServices/containers/blobs/delete` | DeleteBlob, BlobBatch delete (bulk—up to 256 keys per request) |

The smallest predefined role covering all three is **`Storage Blob Data Contributor`**. `Storage Blob Data Owner` is a superset and is only needed if you additionally require POSIX ACL management on ADLS Gen2.

**SAS token**—minimum permissions at container scope: `r` (read) + `w` (write) + `d` (delete) + `l` (list), that is a container-scoped SAS with **`rwdl`**.

**ADLS Gen2 with POSIX ACLs**: if the storage account has hierarchical namespace enabled and you use ACL-based access control instead of RBAC, the principal needs Execute (`X`) on every parent directory and Read / Write / Delete on the objects in scope. RBAC (`Storage Blob Data Contributor`) is simpler and is recommended unless you have a specific ACL requirement.

**Configure:**

 1. Locate the `objectstore` attribute in `values.yaml`.
 2. Add Azure Blob Storage configuration. For more information, see [Azure Blob Storage binding spec](https://docs.dapr.io/reference/components-reference/supported-bindings/blobstorage/)

 ```yaml
 objectstore:
 enabled: true
 spec:
 type: bindings.azure.blobstorage
 version: v1
 metadata:
 - name: accountName
 value: "your-storage-account-name"
 - name: accountKey
 value: "your-storage-account-key"
 - name: containerName
 value: "your-container-name"
 ```

</TabItem>
</Tabs>

### Secret storage

Self-Deployed Runtime fetches secrets from a secret store to connect to the source systems. The secret store references are used to configure the workflow. Configure the secret store that aligns with your security infrastructure:

:::info Did you know?
Dapr supports additional secret stores which aren't mentioned here. For more information, see [Dapr secret store documentation](https://docs.dapr.io/reference/components-reference/supported-secret-stores/) for other configurations.
:::

:::warning Secret content format and naming
When storing credentials, follow the [secret naming and format requirements](https://docs.atlan.com/product/connections/self-deployed-runtime/how-tos/configure-workflow-execution#secret-content-format).
:::

<Tabs>
<TabItem value="aws-secret-manager" label="AWS Secret Manager" default>
 
 1. Locate the `secretstore` attribute in `values.yaml`.
 2. Add AWS Secret Manager configuration. For more information, see [AWS Secrets Manager](https://docs.dapr.io/reference/components-reference/supported-secret-stores/aws-secret-manager/)

 ```yaml
 secretstore:
 enabled: true
 spec:
 type: secretstores.aws.secretmanager
 version: v1
 metadata:
 - name: region # required, region in which secret is hosted
 value: <secret-region>
 # Needed if IAM authentication is not used
 - name: accessKey
 value: ""
 - name: secretKey
 value: ""
 ```

If you are using IAM role / IRSA authentication, leave `accessKey` and `secretKey` empty.

If you are using an IAM user instead, set:
- `accessKey` to the IAM user's access key ID
- `secretKey` to the IAM user's secret access key

That IAM user must have permission to read the target secret from AWS Secrets Manager:

```json
{
 "Version": "2012-10-17",
 "Statement": [
 {
 "Effect": "Allow",
 "Action": [
 "secretsmanager:GetSecretValue",
 "secretsmanager:DescribeSecret"
 ],
 "Resource": "arn:aws:secretsmanager:<region>:<account-id>:secret:<secret-name>*"
 }
 ]
}
```

:::note
Include the trailing `*` in the secret ARN. AWS appends a random suffix to secret names in the ARN, so omitting it can cause access failures.
:::

</TabItem>
<TabItem value="azure-key-vault" label="Azure Key Vault">

 1. Locate the `secretstore` attribute in `values.yaml`.
 2. Add Azure Key Vault configuration. For more information, see [Azure Key Vault secret store](https://docs.dapr.io/reference/components-reference/supported-secret-stores/azure-keyvault/)

 ```yaml
 secretstore:
 enabled: true
 spec:
 type: secretstores.azure.keyvault
 version: v1
 metadata:
 - name: vaultName
 value: "<your-keyvault-name>"
 - name: azureTenantId
 value: "<your-tenant-id>"
 - name: azureClientId
 value: "<your-client-id>"
 - name: azureClientSecret
 value: "<your-client-secret>"
 - name: azureEnvironment
 value: "AZUREPUBLICCLOUD" # Optional: AZUREPUBLICCLOUD, AZURECHINACLOUD, AZUREUSGOVERNMENTCLOUD, AZUREGERMANCLOUD
 ```
 Azure Key Vault supports multiple authentication methods:
 - **Client Secret**: Use `azureClientSecret` with tenant ID and client ID
 - **Certificate**: Use `azureCertificateFile` instead of client secret
 - **Managed Identity**: Omit authentication fields and use Azure managed identity

 For detailed authentication setup, see the [Authenticating to Azure](https://docs.dapr.io/developing-applications/integrations/azure/azure-authentication/authenticating-azure/) documentation.

</TabItem>
<TabItem value="gcp-secret-manager" label="GCP Secret Manager">

1. Locate the `secretstore` attribute in `values.yaml`.
2. Add Google Cloud Secret Manager configuration. For more information, see [GCP Secret Manager](https://docs.dapr.io/reference/components-reference/supported-secret-stores/gcp-secret-manager/)

 The GCP service account used in this configuration must have the `Secret Manager Secret Accessor` role (`roles/secretmanager.secretAccessor`) on the project where your secrets are stored. The metadata values below come from the service account's JSON key file.

 ```yaml
 secretstore:
 enabled: true
 spec:
 type: secretstores.gcp.secretmanager
 version: v1
 metadata:
 - name: type
 value: "service_account"
 - name: project_id
 value: "<project-id>"
 - name: private_key_id
 value: "<private-key-id>"
 - name: private_key
 value: "<private-key>"
 - name: client_email
 value: "<client-email>"
 - name: client_id
 value: "<client-id>"
 - name: auth_uri
 value: "https://accounts.google.com/o/oauth2/auth"
 - name: token_uri
 value: "https://oauth2.googleapis.com/token"
 - name: auth_provider_x509_cert_url
 value: "https://www.googleapis.com/oauth2/v1/certs"
 - name: client_x509_cert_url
 value: "https://www.googleapis.com/robot/v1/metadata/x509/<client-email>"
 ```

</TabItem>
<TabItem value="hashicorp-vault" label="HashiCorp Vault">

1. Locate the `secretstore` attribute in `values.yaml`.
2. Add HashiCorp Vault configuration. For more information, see [HashiCorp Vault](https://docs.dapr.io/reference/components-reference/supported-secret-stores/hashicorp-vault/)

 ```yaml
 secretstore:
 enabled: true
 spec:
 type: secretstores.hashicorp.vault
 version: v1
 metadata:
 - name: vaultAddr
 value: "[vault_address]" # Optional. Default: "https://127.0.0.1:8200"
 - name: caCert # Optional. This or caPath or caPem
 value: "[ca_cert]"
 - name: caPath # Optional. This or CaCert or caPem
 value: "[path_to_ca_cert_file]"
 - name: caPem # Optional. This or CaCert or CaPath
 value: "[encoded_ca_cert_pem]"
 - name: skipVerify # Optional. Default: false
 value: "[skip_tls_verification]"
 - name: tlsServerName # Optional.
 value: "[tls_config_server_name]"
 - name: vaultTokenMountPath # Required if vaultToken not provided. Path to token file.
 value: "[path_to_file_containing_token]"
 - name: vaultToken # Required if vaultTokenMountPath not provided. Token value.
 value: "[vault_token]"
 - name: vaultKVPrefix # Optional. Default: "dapr"
 value: "[vault_prefix]"
 - name: vaultKVUsePrefix # Optional. default: "true"
 value: "[true/false]"
 - name: enginePath # Optional. default: "secret"
 value: "secret"
 - name: vaultValueType # Optional. default: "map"
 value: "map"
 ```

</TabItem>
<TabItem value="kubernetes-secrets" label="Kubernetes Secrets">

1. Locate the `secretstore` attribute in `values.yaml`.
2. Add Kubernetes native secret storage. For more information, see [Kubernetes secrets](https://docs.dapr.io/reference/components-reference/supported-secret-stores/kubernetes-secret-store/)

 ```yaml
 secretstore:
 enabled: true
 spec:
 type: secretstores.kubernetes
 version: v1
 metadata:
 - name: defaultNamespace
 value: "default" # Optional: Default namespace to retrieve secrets from
 - name: kubeconfigPath
 value: "/path/to/kubeconfig" # Optional: Path to kubeconfig file
 ```
 When Dapr is deployed to a Kubernetes cluster, a secret store with the name `kubernetes` is automatically provisioned. You can use this native Kubernetes secret store with no need to create, deploy or maintain a component configuration file.

</TabItem>
<TabItem value="environment-variable-based" label="Environment Variables">

1. Locate the `secretstore` attribute in `values.yaml`.
2. Add Local environment variables as the spec. For more information, see [Local Environment Variables](https://docs.dapr.io/reference/components-reference/supported-secret-stores/envvar-secret-store/)

 ```yaml
 secretstore:
 enabled: true
 spec:
 type: secretstores.local.env
 version: v1
 ```

</TabItem>
</Tabs>

### Image source

Choose how the cluster pulls the app image. Most installs use Atlan's Docker Hub directly; mirror to a private registry if your organization requires it.

<Tabs>
<TabItem value="docker-hub" label="Public Docker Hub" default>

The chart pulls the app image from Atlan's Docker Hub at runtime. The pod needs a Kubernetes secret containing your Docker Hub PAT to authenticate:

```bash
kubectl create secret docker-registry atlan-docker-secret \
 --docker-server=docker.io \
 --docker-username=YOUR_USERNAME \
 --docker-password=YOUR_PAT_TOKEN \
 -n <namespace>
```

- Replace `YOUR_USERNAME` with the Docker Hub username provided by Atlan.
- Replace `YOUR_PAT_TOKEN` with the Personal Access Token (PAT) provided by Atlan.
- Replace `<namespace>` with the namespace you need to install the chart into. The secret and the release must live in the same namespace, or the pod fails with `ImagePullBackOff`.

The downloaded `values.yaml` already references this secret under `imagePullSecrets`. If you use a different secret name, update that field in the file.

</TabItem>
<TabItem value="private-registry" label="Private image repo">

Mirror the Atlan image to your enterprise registry and update `values.yaml` to point at it.

1. Authenticate with Docker Hub using the PAT from Atlan, then pull the source image. The image and tag come from `image.repository` and `image.tag` in the downloaded `values.yaml`:

 ```bash
 docker login -u atlanhq
 # When prompted for password, enter the PAT provided by Atlan
 docker pull <image.repository>:<image.tag>
 ```

2. Push the image to your enterprise's registry. Note down the new repository name and image tag.

3. Update `image.repository` and `image.tag` in `values.yaml` with the new values.

4. If your private registry requires authentication, create an image-pull secret in the target namespace and set `imagePullSecrets` in `values.yaml` to its name.

</TabItem>
</Tabs>

<h2 id="deploy-app">Deploy app</h2>

Follow these steps to deploy the secure app:

* Install the helm chart. The chart directory now carries your edited `values.yaml`, so no `-f` flag is needed:

 ```bash
 helm install {{deploymentValues.helmChartName}}-release ./{{deploymentValues.helmChartName}} -n <namespace>
 ```

 - Replace `<namespace>` with your target Kubernetes namespace.
 - The helm chart name `{{deploymentValues.helmChartName}}` is automatically used from your selected app.

The deployment process typically takes a few minutes to complete depending on factors like Kubernetes cluster resource availability, private image repository download time etc.

<h2 id="verify-app">Verify app</h2>

Follow these steps to verify deployment:

### Verify deployment status on cluster

1. Check pod status:

 ```bash
 kubectl get pods -n <namespace>
 ```

 The output appears similar to:

 ```
 NAME READY STATUS RESTARTS AGE
 <helm-chart-name>-release-<helm-chart-name>-5dff95cd85-cvk5z 1/1 Running 0 2m
 ```
 
 Replace `<helm-chart-name>` with your app's helm chart name (shown in the prerequisites section earlier in this guide).

 The pod status shows `Running` with `1/1` ready containers.

2. Verify logs for the running pod
 
 ```bash
 kubectl logs -n <namespace> -l app.kubernetes.io/name={{deploymentValues.helmChartName}} --tail=50 -f
 ```
 **Example application logs**: Look for these key log messages that confirm successful deployment:

 * `Uvicorn running on http://0.0.0.0:8000` - Web server started
 * `Workflow engine initialized` - Workflow processing ready
 * `dapr initialized. Status: Running` - Dapr runtime active
 * `Starting worker with task queue: atlan-<package-name>-DEPLOYMENT_NAME` - Worker process started (replace `<package-name>` with your app's package name)
 * `GET /server/ready 200` - Health check endpoint responding

### Verify registration via Atlan UI

Once the App is successfully deployed, it communicates to the Atlan tenant and registers itself. Verify App registration is successful in Atlan:

1. In the same Atlan tenant, navigate to **Workflows** > **Agent**.
2. Look for an entry named `<app_name>-<deployment_name>`, where `<app_name>` matches your selected app (for example, "Oracle" or "Microsoft SQL Server") and `<deployment_name>` is the deployment name you entered when generating the config.
3. Confirm the agent status displays as **Active**.

Agent registration and status takes a couple of minutes to reflect in the Atlan UI.

<h2 id="next-steps">Next steps</h2>

* [Configure workflow execution](https://docs.atlan.com/product/connections/self-deployed-runtime/how-tos/configure-workflow-execution): Set up workflow execution with secret retrieval for your Self-deployed Runtime

---

## Install on Kubernetes - Microsoft Fabric

URL: https://docs.atlan.com/product/connections/self-deployed-runtime/how-tos/install-on-kubernetes
**Connector:** Microsoft Fabric (business-intelligence)

> Install an App on Kubernetes using Helm charts, Docker images, and specific configuration

:::info **Did you know?** 
SDR requires additional enablement and licensing. Contact your Atlan representative for details.
:::

:::warning Use the guided install wizard instead
**New Self-Deployed Runtime setups are encouraged to use the [guided install wizard](https://docs.atlan.com/product/connections/self-deployed-runtime/how-tos/install-guided).** It assembles a complete guide tailored to your lifecycle mode, platform, and image procurement on a single page—and it's where new setup options (for example, HTTP proxy and custom CA trust) are documented going forward.

This page is kept for existing users who already reference it and may not include the latest steps.
:::

<h2 id="prerequisites">Prerequisites</h2>

Before you begin, make sure you have:

* `kubectl` installed and configured with administrative access to your target Kubernetes cluster
* Helm version 3.0 or later installed on your deployment machine
* A [Docker Hub Personal Access Token (PAT)](https://start.1password.com/open/i?a=WAVUZSKJO5GMNMVBYWAWECXIUE&v=ouvp3xf5334cxoamyiipzjlewy&i=p76avgzmkkcbftldcuvr5jcof4&h=atlanhq.1password.com) from Atlan
* App-specific helm chart name: `{{deploymentValues.helmChartName}}` 
* Object storage: AWS S3, Google Cloud Storage, or Azure Blob Storage with read/write permissions
* Secret store access: AWS Secret Manager, Azure Key Vault, GCP Secret Manager, HashiCorp Vault, or Kubernetes Secrets with read permissions

:::warning For security reasons, the Docker Hub PAT Token is regenerated on a periodic basis. 
In case the token is embedded in automation scripts or CI/CD pipelines, those jobs may fail. 
Contact your Atlan representative for the latest token.
:::

<h2 id="download-required-files">Download required files</h2>

<h3 id="download-helm-chart">Download Helm chart</h3>

Download the Helm chart for the app:

```bash
helm pull oci://registry-1.docker.io/atlanhq/{{deploymentValues.helmChartName}} --untar
```

This unpacks the chart's `Chart.yaml`, `templates/`, and a default `values.yaml` into `./{{deploymentValues.helmChartName}}/`. You'll replace this default `values.yaml` with your Marketplace copy in the next step.

<h3 id="download-values-yaml">Download values.yaml</h3>

Atlan generates the helm `values.yaml` for your runtime directly from the Marketplace UI, including the OAuth client credentials your runtime uses to authenticate to your tenant.

1. Sign in to your Atlan tenant as an administrator, open **Connector** > **Marketplace**, select the app you want to deploy, and click **Download config for Self-Deployed Runtime** in the right-hand sidebar.

2. In the dialog, keep **New deployment** selected (this mints the OAuth client and full config for a fresh runtime), choose **Kubernetes (Helm)** as the deployment target, and enter a **Deployment name**: a short identifier (lowercase letters, digits, and dashes) that identifies this runtime; the agent in **Workflows > Agent** is named `<app_name>-<deployment_name>`.

3. Click **Generate**. Atlan mints a dedicated OAuth client and produces a `values.yaml` file with:
 - `global.atlanBaseUrl`, `global.clientId`, and `global.clientSecret` already filled in.
 - `image.repository`, `image.tag`, and `name` pinned to the active version for your tenant.
 - `objectstore` and `secretstore` placeholders for you to configure below.

<h3 id="replace-chart-values">Replace chart values.yaml</h3>

Replace the default `values.yaml` inside the unpacked chart with the `values.yaml` you downloaded from the Marketplace.

From this point on, all edits to `values.yaml` must be made inside `./{{deploymentValues.helmChartName}}/`.

<h2 id="modify-values-yaml">Modify values.yaml</h2>

### Object storage

Self-Deployed Runtime needs a store for reading or writing files. Configure the object storage that matches your environment:

:::tip Don't see your preferred object store?
If your preferred object store isn't listed here, [reach out to Atlan support](https://docs.atlan.com/support/submit-request). Support for additional object stores may be available.
:::

<Tabs>
<TabItem value="aws-s3" label="AWS S3" default>

**Required permissions:**

Apply object-level actions to `arn:aws:s3:::BUCKET/*` and the list action to `arn:aws:s3:::BUCKET` in separate IAM statement entries.

| IAM action | Operations covered |
|---|---|
| `s3:GetObject` | GetObject (full and byte-range), HeadObject |
| `s3:PutObject` | PutObject, CreateMultipartUpload, UploadPart, CompleteMultipartUpload |
| `s3:AbortMultipartUpload` | Abort in-flight multipart upload on error (required for streaming write error paths) |
| `s3:DeleteObject` | DeleteObject and DeleteObjects (bulk batch—same IAM action) |
| `s3:ListBucket` | ListObjectsV2—bucket-level permission, not object-level |

```json
{
 "Version": "2012-10-17",
 "Statement": [
 {
 "Effect": "Allow",
 "Action": [
 "s3:GetObject",
 "s3:PutObject",
 "s3:AbortMultipartUpload",
 "s3:DeleteObject"
 ],
 "Resource": "arn:aws:s3:::YOUR-BUCKET/*"
 },
 {
 "Effect": "Allow",
 "Action": "s3:ListBucket",
 "Resource": "arn:aws:s3:::YOUR-BUCKET"
 }
 ]
}
```

**AssumeRole**: when using `assumeRoleArn`, the caller identity additionally needs `sts:AssumeRole` on the target role ARN. The role itself holds the bucket policy described earlier.

**Configure:**

 1. Locate the `objectstore` attribute in `values.yaml`.
 2. Add AWS S3 configuration. For more information, see [AWS S3 Binding Spec](https://docs.dapr.io/reference/components-reference/supported-bindings/s3/).

 ```yaml
 objectstore:
 enabled: true
 spec:
 type: bindings.aws.s3
 version: v1
 metadata:
 - name: accessKey #optional, leave this empty for iam authentication
 value: ""
 - name: secretKey #optional, leave this empty for iam authentication
 value: ""
 - name: bucket #required, name of the bucket where application can write
 value: "<bucket-name>"
 - name: region #required, region of the bucket where application can write
 value: "<bucket-region>"
 - name: forcePathStyle
 value: "true"
 ```

</TabItem>
<TabItem value="gcp-storage" label="Google Cloud Storage">

**Required permissions:**

| IAM permission | Operations covered |
|---|---|
| `storage.objects.get` | GetObject (full and byte-range), object metadata / HeadObject equivalent |
| `storage.objects.create` | PutObject, resumable / streaming write |
| `storage.objects.delete` | DeleteObject (GCS has no native bulk-delete API—`delete_prefix` issues parallel single-object deletes) |
| `storage.objects.list` | ListObjects |

No `storage.buckets.*` permissions are needed. The smallest predefined role that covers all four is **`roles/storage.objectAdmin`** scoped to the bucket. Alternatively, create a custom role with exactly these four permissions.

**Configure:**

 1. Locate the `objectstore` attribute in `values.yaml`.
 2. Add Google Cloud Storage configuration. For more information, see [GCP Storage Bucket binding spec](https://docs.dapr.io/reference/components-reference/supported-bindings/gcpbucket/)

 ```yaml
 objectstore:
 enabled: true
 spec:
 type: bindings.gcp.bucket
 version: v1
 metadata:
 - name: bucket
 value: "your-gcs-bucket-name"
 - name: type
 value: "service_account"
 - name: project_id
 value: "your-gcp-project-id"
 ```

</TabItem>
<TabItem value="azure-blob" label="Azure Blob Storage">

**Required permissions:**

**RBAC**—assign at container or storage-account scope:

| RBAC action | Operations covered |
|---|---|
| `Microsoft.Storage/storageAccounts/blobServices/containers/blobs/read` | GetBlob, GetBlobProperties (HEAD), ListBlobs, byte-range GET |
| `Microsoft.Storage/storageAccounts/blobServices/containers/blobs/write` | PutBlob, PutBlock + PutBlockList (streaming / block write) |
| `Microsoft.Storage/storageAccounts/blobServices/containers/blobs/delete` | DeleteBlob, BlobBatch delete (bulk—up to 256 keys per request) |

The smallest predefined role covering all three is **`Storage Blob Data Contributor`**. `Storage Blob Data Owner` is a superset and is only needed if you additionally require POSIX ACL management on ADLS Gen2.

**SAS token**—minimum permissions at container scope: `r` (read) + `w` (write) + `d` (delete) + `l` (list), that is a container-scoped SAS with **`rwdl`**.

**ADLS Gen2 with POSIX ACLs**: if the storage account has hierarchical namespace enabled and you use ACL-based access control instead of RBAC, the principal needs Execute (`X`) on every parent directory and Read / Write / Delete on the objects in scope. RBAC (`Storage Blob Data Contributor`) is simpler and is recommended unless you have a specific ACL requirement.

**Configure:**

 1. Locate the `objectstore` attribute in `values.yaml`.
 2. Add Azure Blob Storage configuration. For more information, see [Azure Blob Storage binding spec](https://docs.dapr.io/reference/components-reference/supported-bindings/blobstorage/)

 ```yaml
 objectstore:
 enabled: true
 spec:
 type: bindings.azure.blobstorage
 version: v1
 metadata:
 - name: accountName
 value: "your-storage-account-name"
 - name: accountKey
 value: "your-storage-account-key"
 - name: containerName
 value: "your-container-name"
 ```

</TabItem>
</Tabs>

### Secret storage

Self-Deployed Runtime fetches secrets from a secret store to connect to the source systems. The secret store references are used to configure the workflow. Configure the secret store that aligns with your security infrastructure:

:::info Did you know?
Dapr supports additional secret stores which aren't mentioned here. For more information, see [Dapr secret store documentation](https://docs.dapr.io/reference/components-reference/supported-secret-stores/) for other configurations.
:::

:::warning Secret content format and naming
When storing credentials, follow the [secret naming and format requirements](https://docs.atlan.com/product/connections/self-deployed-runtime/how-tos/configure-workflow-execution#secret-content-format).
:::

<Tabs>
<TabItem value="aws-secret-manager" label="AWS Secret Manager" default>
 
 1. Locate the `secretstore` attribute in `values.yaml`.
 2. Add AWS Secret Manager configuration. For more information, see [AWS Secrets Manager](https://docs.dapr.io/reference/components-reference/supported-secret-stores/aws-secret-manager/)

 ```yaml
 secretstore:
 enabled: true
 spec:
 type: secretstores.aws.secretmanager
 version: v1
 metadata:
 - name: region # required, region in which secret is hosted
 value: <secret-region>
 # Needed if IAM authentication is not used
 - name: accessKey
 value: ""
 - name: secretKey
 value: ""
 ```

If you are using IAM role / IRSA authentication, leave `accessKey` and `secretKey` empty.

If you are using an IAM user instead, set:
- `accessKey` to the IAM user's access key ID
- `secretKey` to the IAM user's secret access key

That IAM user must have permission to read the target secret from AWS Secrets Manager:

```json
{
 "Version": "2012-10-17",
 "Statement": [
 {
 "Effect": "Allow",
 "Action": [
 "secretsmanager:GetSecretValue",
 "secretsmanager:DescribeSecret"
 ],
 "Resource": "arn:aws:secretsmanager:<region>:<account-id>:secret:<secret-name>*"
 }
 ]
}
```

:::note
Include the trailing `*` in the secret ARN. AWS appends a random suffix to secret names in the ARN, so omitting it can cause access failures.
:::

</TabItem>
<TabItem value="azure-key-vault" label="Azure Key Vault">

 1. Locate the `secretstore` attribute in `values.yaml`.
 2. Add Azure Key Vault configuration. For more information, see [Azure Key Vault secret store](https://docs.dapr.io/reference/components-reference/supported-secret-stores/azure-keyvault/)

 ```yaml
 secretstore:
 enabled: true
 spec:
 type: secretstores.azure.keyvault
 version: v1
 metadata:
 - name: vaultName
 value: "<your-keyvault-name>"
 - name: azureTenantId
 value: "<your-tenant-id>"
 - name: azureClientId
 value: "<your-client-id>"
 - name: azureClientSecret
 value: "<your-client-secret>"
 - name: azureEnvironment
 value: "AZUREPUBLICCLOUD" # Optional: AZUREPUBLICCLOUD, AZURECHINACLOUD, AZUREUSGOVERNMENTCLOUD, AZUREGERMANCLOUD
 ```
 Azure Key Vault supports multiple authentication methods:
 - **Client Secret**: Use `azureClientSecret` with tenant ID and client ID
 - **Certificate**: Use `azureCertificateFile` instead of client secret
 - **Managed Identity**: Omit authentication fields and use Azure managed identity

 For detailed authentication setup, see the [Authenticating to Azure](https://docs.dapr.io/developing-applications/integrations/azure/azure-authentication/authenticating-azure/) documentation.

</TabItem>
<TabItem value="gcp-secret-manager" label="GCP Secret Manager">

1. Locate the `secretstore` attribute in `values.yaml`.
2. Add Google Cloud Secret Manager configuration. For more information, see [GCP Secret Manager](https://docs.dapr.io/reference/components-reference/supported-secret-stores/gcp-secret-manager/)

 The GCP service account used in this configuration must have the `Secret Manager Secret Accessor` role (`roles/secretmanager.secretAccessor`) on the project where your secrets are stored. The metadata values below come from the service account's JSON key file.

 ```yaml
 secretstore:
 enabled: true
 spec:
 type: secretstores.gcp.secretmanager
 version: v1
 metadata:
 - name: type
 value: "service_account"
 - name: project_id
 value: "<project-id>"
 - name: private_key_id
 value: "<private-key-id>"
 - name: private_key
 value: "<private-key>"
 - name: client_email
 value: "<client-email>"
 - name: client_id
 value: "<client-id>"
 - name: auth_uri
 value: "https://accounts.google.com/o/oauth2/auth"
 - name: token_uri
 value: "https://oauth2.googleapis.com/token"
 - name: auth_provider_x509_cert_url
 value: "https://www.googleapis.com/oauth2/v1/certs"
 - name: client_x509_cert_url
 value: "https://www.googleapis.com/robot/v1/metadata/x509/<client-email>"
 ```

</TabItem>
<TabItem value="hashicorp-vault" label="HashiCorp Vault">

1. Locate the `secretstore` attribute in `values.yaml`.
2. Add HashiCorp Vault configuration. For more information, see [HashiCorp Vault](https://docs.dapr.io/reference/components-reference/supported-secret-stores/hashicorp-vault/)

 ```yaml
 secretstore:
 enabled: true
 spec:
 type: secretstores.hashicorp.vault
 version: v1
 metadata:
 - name: vaultAddr
 value: "[vault_address]" # Optional. Default: "https://127.0.0.1:8200"
 - name: caCert # Optional. This or caPath or caPem
 value: "[ca_cert]"
 - name: caPath # Optional. This or CaCert or caPem
 value: "[path_to_ca_cert_file]"
 - name: caPem # Optional. This or CaCert or CaPath
 value: "[encoded_ca_cert_pem]"
 - name: skipVerify # Optional. Default: false
 value: "[skip_tls_verification]"
 - name: tlsServerName # Optional.
 value: "[tls_config_server_name]"
 - name: vaultTokenMountPath # Required if vaultToken not provided. Path to token file.
 value: "[path_to_file_containing_token]"
 - name: vaultToken # Required if vaultTokenMountPath not provided. Token value.
 value: "[vault_token]"
 - name: vaultKVPrefix # Optional. Default: "dapr"
 value: "[vault_prefix]"
 - name: vaultKVUsePrefix # Optional. default: "true"
 value: "[true/false]"
 - name: enginePath # Optional. default: "secret"
 value: "secret"
 - name: vaultValueType # Optional. default: "map"
 value: "map"
 ```

</TabItem>
<TabItem value="kubernetes-secrets" label="Kubernetes Secrets">

1. Locate the `secretstore` attribute in `values.yaml`.
2. Add Kubernetes native secret storage. For more information, see [Kubernetes secrets](https://docs.dapr.io/reference/components-reference/supported-secret-stores/kubernetes-secret-store/)

 ```yaml
 secretstore:
 enabled: true
 spec:
 type: secretstores.kubernetes
 version: v1
 metadata:
 - name: defaultNamespace
 value: "default" # Optional: Default namespace to retrieve secrets from
 - name: kubeconfigPath
 value: "/path/to/kubeconfig" # Optional: Path to kubeconfig file
 ```
 When Dapr is deployed to a Kubernetes cluster, a secret store with the name `kubernetes` is automatically provisioned. You can use this native Kubernetes secret store with no need to create, deploy or maintain a component configuration file.

</TabItem>
<TabItem value="environment-variable-based" label="Environment Variables">

1. Locate the `secretstore` attribute in `values.yaml`.
2. Add Local environment variables as the spec. For more information, see [Local Environment Variables](https://docs.dapr.io/reference/components-reference/supported-secret-stores/envvar-secret-store/)

 ```yaml
 secretstore:
 enabled: true
 spec:
 type: secretstores.local.env
 version: v1
 ```

</TabItem>
</Tabs>

### Image source

Choose how the cluster pulls the app image. Most installs use Atlan's Docker Hub directly; mirror to a private registry if your organization requires it.

<Tabs>
<TabItem value="docker-hub" label="Public Docker Hub" default>

The chart pulls the app image from Atlan's Docker Hub at runtime. The pod needs a Kubernetes secret containing your Docker Hub PAT to authenticate:

```bash
kubectl create secret docker-registry atlan-docker-secret \
 --docker-server=docker.io \
 --docker-username=YOUR_USERNAME \
 --docker-password=YOUR_PAT_TOKEN \
 -n <namespace>
```

- Replace `YOUR_USERNAME` with the Docker Hub username provided by Atlan.
- Replace `YOUR_PAT_TOKEN` with the Personal Access Token (PAT) provided by Atlan.
- Replace `<namespace>` with the namespace you need to install the chart into. The secret and the release must live in the same namespace, or the pod fails with `ImagePullBackOff`.

The downloaded `values.yaml` already references this secret under `imagePullSecrets`. If you use a different secret name, update that field in the file.

</TabItem>
<TabItem value="private-registry" label="Private image repo">

Mirror the Atlan image to your enterprise registry and update `values.yaml` to point at it.

1. Authenticate with Docker Hub using the PAT from Atlan, then pull the source image. The image and tag come from `image.repository` and `image.tag` in the downloaded `values.yaml`:

 ```bash
 docker login -u atlanhq
 # When prompted for password, enter the PAT provided by Atlan
 docker pull <image.repository>:<image.tag>
 ```

2. Push the image to your enterprise's registry. Note down the new repository name and image tag.

3. Update `image.repository` and `image.tag` in `values.yaml` with the new values.

4. If your private registry requires authentication, create an image-pull secret in the target namespace and set `imagePullSecrets` in `values.yaml` to its name.

</TabItem>
</Tabs>

<h2 id="deploy-app">Deploy app</h2>

Follow these steps to deploy the secure app:

* Install the helm chart. The chart directory now carries your edited `values.yaml`, so no `-f` flag is needed:

 ```bash
 helm install {{deploymentValues.helmChartName}}-release ./{{deploymentValues.helmChartName}} -n <namespace>
 ```

 - Replace `<namespace>` with your target Kubernetes namespace.
 - The helm chart name `{{deploymentValues.helmChartName}}` is automatically used from your selected app.

The deployment process typically takes a few minutes to complete depending on factors like Kubernetes cluster resource availability, private image repository download time etc.

<h2 id="verify-app">Verify app</h2>

Follow these steps to verify deployment:

### Verify deployment status on cluster

1. Check pod status:

 ```bash
 kubectl get pods -n <namespace>
 ```

 The output appears similar to:

 ```
 NAME READY STATUS RESTARTS AGE
 <helm-chart-name>-release-<helm-chart-name>-5dff95cd85-cvk5z 1/1 Running 0 2m
 ```
 
 Replace `<helm-chart-name>` with your app's helm chart name (shown in the prerequisites section earlier in this guide).

 The pod status shows `Running` with `1/1` ready containers.

2. Verify logs for the running pod
 
 ```bash
 kubectl logs -n <namespace> -l app.kubernetes.io/name={{deploymentValues.helmChartName}} --tail=50 -f
 ```
 **Example application logs**: Look for these key log messages that confirm successful deployment:

 * `Uvicorn running on http://0.0.0.0:8000` - Web server started
 * `Workflow engine initialized` - Workflow processing ready
 * `dapr initialized. Status: Running` - Dapr runtime active
 * `Starting worker with task queue: atlan-<package-name>-DEPLOYMENT_NAME` - Worker process started (replace `<package-name>` with your app's package name)
 * `GET /server/ready 200` - Health check endpoint responding

### Verify registration via Atlan UI

Once the App is successfully deployed, it communicates to the Atlan tenant and registers itself. Verify App registration is successful in Atlan:

1. In the same Atlan tenant, navigate to **Workflows** > **Agent**.
2. Look for an entry named `<app_name>-<deployment_name>`, where `<app_name>` matches your selected app (for example, "Oracle" or "Microsoft SQL Server") and `<deployment_name>` is the deployment name you entered when generating the config.
3. Confirm the agent status displays as **Active**.

Agent registration and status takes a couple of minutes to reflect in the Atlan UI.

<h2 id="next-steps">Next steps</h2>

* [Configure workflow execution](https://docs.atlan.com/product/connections/self-deployed-runtime/how-tos/configure-workflow-execution): Set up workflow execution with secret retrieval for your Self-deployed Runtime

---

## Install on Kubernetes - Iceberg

URL: https://docs.atlan.com/product/connections/self-deployed-runtime/how-tos/install-on-kubernetes
**Connector:** Iceberg (data-lakehouses)

> Install an App on Kubernetes using Helm charts, Docker images, and specific configuration

:::info **Did you know?** 
SDR requires additional enablement and licensing. Contact your Atlan representative for details.
:::

:::warning Use the guided install wizard instead
**New Self-Deployed Runtime setups are encouraged to use the [guided install wizard](https://docs.atlan.com/product/connections/self-deployed-runtime/how-tos/install-guided).** It assembles a complete guide tailored to your lifecycle mode, platform, and image procurement on a single page—and it's where new setup options (for example, HTTP proxy and custom CA trust) are documented going forward.

This page is kept for existing users who already reference it and may not include the latest steps.
:::

<h2 id="prerequisites">Prerequisites</h2>

Before you begin, make sure you have:

* `kubectl` installed and configured with administrative access to your target Kubernetes cluster
* Helm version 3.0 or later installed on your deployment machine
* A [Docker Hub Personal Access Token (PAT)](https://start.1password.com/open/i?a=WAVUZSKJO5GMNMVBYWAWECXIUE&v=ouvp3xf5334cxoamyiipzjlewy&i=p76avgzmkkcbftldcuvr5jcof4&h=atlanhq.1password.com) from Atlan
* App-specific helm chart name: `{{deploymentValues.helmChartName}}` 
* Object storage: AWS S3, Google Cloud Storage, or Azure Blob Storage with read/write permissions
* Secret store access: AWS Secret Manager, Azure Key Vault, GCP Secret Manager, HashiCorp Vault, or Kubernetes Secrets with read permissions

:::warning For security reasons, the Docker Hub PAT Token is regenerated on a periodic basis. 
In case the token is embedded in automation scripts or CI/CD pipelines, those jobs may fail. 
Contact your Atlan representative for the latest token.
:::

<h2 id="download-required-files">Download required files</h2>

<h3 id="download-helm-chart">Download Helm chart</h3>

Download the Helm chart for the app:

```bash
helm pull oci://registry-1.docker.io/atlanhq/{{deploymentValues.helmChartName}} --untar
```

This unpacks the chart's `Chart.yaml`, `templates/`, and a default `values.yaml` into `./{{deploymentValues.helmChartName}}/`. You'll replace this default `values.yaml` with your Marketplace copy in the next step.

<h3 id="download-values-yaml">Download values.yaml</h3>

Atlan generates the helm `values.yaml` for your runtime directly from the Marketplace UI, including the OAuth client credentials your runtime uses to authenticate to your tenant.

1. Sign in to your Atlan tenant as an administrator, open **Connector** > **Marketplace**, select the app you want to deploy, and click **Download config for Self-Deployed Runtime** in the right-hand sidebar.

2. In the dialog, keep **New deployment** selected (this mints the OAuth client and full config for a fresh runtime), choose **Kubernetes (Helm)** as the deployment target, and enter a **Deployment name**: a short identifier (lowercase letters, digits, and dashes) that identifies this runtime; the agent in **Workflows > Agent** is named `<app_name>-<deployment_name>`.

3. Click **Generate**. Atlan mints a dedicated OAuth client and produces a `values.yaml` file with:
 - `global.atlanBaseUrl`, `global.clientId`, and `global.clientSecret` already filled in.
 - `image.repository`, `image.tag`, and `name` pinned to the active version for your tenant.
 - `objectstore` and `secretstore` placeholders for you to configure below.

<h3 id="replace-chart-values">Replace chart values.yaml</h3>

Replace the default `values.yaml` inside the unpacked chart with the `values.yaml` you downloaded from the Marketplace.

From this point on, all edits to `values.yaml` must be made inside `./{{deploymentValues.helmChartName}}/`.

<h2 id="modify-values-yaml">Modify values.yaml</h2>

### Object storage

Self-Deployed Runtime needs a store for reading or writing files. Configure the object storage that matches your environment:

:::tip Don't see your preferred object store?
If your preferred object store isn't listed here, [reach out to Atlan support](https://docs.atlan.com/support/submit-request). Support for additional object stores may be available.
:::

<Tabs>
<TabItem value="aws-s3" label="AWS S3" default>

**Required permissions:**

Apply object-level actions to `arn:aws:s3:::BUCKET/*` and the list action to `arn:aws:s3:::BUCKET` in separate IAM statement entries.

| IAM action | Operations covered |
|---|---|
| `s3:GetObject` | GetObject (full and byte-range), HeadObject |
| `s3:PutObject` | PutObject, CreateMultipartUpload, UploadPart, CompleteMultipartUpload |
| `s3:AbortMultipartUpload` | Abort in-flight multipart upload on error (required for streaming write error paths) |
| `s3:DeleteObject` | DeleteObject and DeleteObjects (bulk batch—same IAM action) |
| `s3:ListBucket` | ListObjectsV2—bucket-level permission, not object-level |

```json
{
 "Version": "2012-10-17",
 "Statement": [
 {
 "Effect": "Allow",
 "Action": [
 "s3:GetObject",
 "s3:PutObject",
 "s3:AbortMultipartUpload",
 "s3:DeleteObject"
 ],
 "Resource": "arn:aws:s3:::YOUR-BUCKET/*"
 },
 {
 "Effect": "Allow",
 "Action": "s3:ListBucket",
 "Resource": "arn:aws:s3:::YOUR-BUCKET"
 }
 ]
}
```

**AssumeRole**: when using `assumeRoleArn`, the caller identity additionally needs `sts:AssumeRole` on the target role ARN. The role itself holds the bucket policy described earlier.

**Configure:**

 1. Locate the `objectstore` attribute in `values.yaml`.
 2. Add AWS S3 configuration. For more information, see [AWS S3 Binding Spec](https://docs.dapr.io/reference/components-reference/supported-bindings/s3/).

 ```yaml
 objectstore:
 enabled: true
 spec:
 type: bindings.aws.s3
 version: v1
 metadata:
 - name: accessKey #optional, leave this empty for iam authentication
 value: ""
 - name: secretKey #optional, leave this empty for iam authentication
 value: ""
 - name: bucket #required, name of the bucket where application can write
 value: "<bucket-name>"
 - name: region #required, region of the bucket where application can write
 value: "<bucket-region>"
 - name: forcePathStyle
 value: "true"
 ```

</TabItem>
<TabItem value="gcp-storage" label="Google Cloud Storage">

**Required permissions:**

| IAM permission | Operations covered |
|---|---|
| `storage.objects.get` | GetObject (full and byte-range), object metadata / HeadObject equivalent |
| `storage.objects.create` | PutObject, resumable / streaming write |
| `storage.objects.delete` | DeleteObject (GCS has no native bulk-delete API—`delete_prefix` issues parallel single-object deletes) |
| `storage.objects.list` | ListObjects |

No `storage.buckets.*` permissions are needed. The smallest predefined role that covers all four is **`roles/storage.objectAdmin`** scoped to the bucket. Alternatively, create a custom role with exactly these four permissions.

**Configure:**

 1. Locate the `objectstore` attribute in `values.yaml`.
 2. Add Google Cloud Storage configuration. For more information, see [GCP Storage Bucket binding spec](https://docs.dapr.io/reference/components-reference/supported-bindings/gcpbucket/)

 ```yaml
 objectstore:
 enabled: true
 spec:
 type: bindings.gcp.bucket
 version: v1
 metadata:
 - name: bucket
 value: "your-gcs-bucket-name"
 - name: type
 value: "service_account"
 - name: project_id
 value: "your-gcp-project-id"
 ```

</TabItem>
<TabItem value="azure-blob" label="Azure Blob Storage">

**Required permissions:**

**RBAC**—assign at container or storage-account scope:

| RBAC action | Operations covered |
|---|---|
| `Microsoft.Storage/storageAccounts/blobServices/containers/blobs/read` | GetBlob, GetBlobProperties (HEAD), ListBlobs, byte-range GET |
| `Microsoft.Storage/storageAccounts/blobServices/containers/blobs/write` | PutBlob, PutBlock + PutBlockList (streaming / block write) |
| `Microsoft.Storage/storageAccounts/blobServices/containers/blobs/delete` | DeleteBlob, BlobBatch delete (bulk—up to 256 keys per request) |

The smallest predefined role covering all three is **`Storage Blob Data Contributor`**. `Storage Blob Data Owner` is a superset and is only needed if you additionally require POSIX ACL management on ADLS Gen2.

**SAS token**—minimum permissions at container scope: `r` (read) + `w` (write) + `d` (delete) + `l` (list), that is a container-scoped SAS with **`rwdl`**.

**ADLS Gen2 with POSIX ACLs**: if the storage account has hierarchical namespace enabled and you use ACL-based access control instead of RBAC, the principal needs Execute (`X`) on every parent directory and Read / Write / Delete on the objects in scope. RBAC (`Storage Blob Data Contributor`) is simpler and is recommended unless you have a specific ACL requirement.

**Configure:**

 1. Locate the `objectstore` attribute in `values.yaml`.
 2. Add Azure Blob Storage configuration. For more information, see [Azure Blob Storage binding spec](https://docs.dapr.io/reference/components-reference/supported-bindings/blobstorage/)

 ```yaml
 objectstore:
 enabled: true
 spec:
 type: bindings.azure.blobstorage
 version: v1
 metadata:
 - name: accountName
 value: "your-storage-account-name"
 - name: accountKey
 value: "your-storage-account-key"
 - name: containerName
 value: "your-container-name"
 ```

</TabItem>
</Tabs>

### Secret storage

Self-Deployed Runtime fetches secrets from a secret store to connect to the source systems. The secret store references are used to configure the workflow. Configure the secret store that aligns with your security infrastructure:

:::info Did you know?
Dapr supports additional secret stores which aren't mentioned here. For more information, see [Dapr secret store documentation](https://docs.dapr.io/reference/components-reference/supported-secret-stores/) for other configurations.
:::

:::warning Secret content format and naming
When storing credentials, follow the [secret naming and format requirements](https://docs.atlan.com/product/connections/self-deployed-runtime/how-tos/configure-workflow-execution#secret-content-format).
:::

<Tabs>
<TabItem value="aws-secret-manager" label="AWS Secret Manager" default>
 
 1. Locate the `secretstore` attribute in `values.yaml`.
 2. Add AWS Secret Manager configuration. For more information, see [AWS Secrets Manager](https://docs.dapr.io/reference/components-reference/supported-secret-stores/aws-secret-manager/)

 ```yaml
 secretstore:
 enabled: true
 spec:
 type: secretstores.aws.secretmanager
 version: v1
 metadata:
 - name: region # required, region in which secret is hosted
 value: <secret-region>
 # Needed if IAM authentication is not used
 - name: accessKey
 value: ""
 - name: secretKey
 value: ""
 ```

If you are using IAM role / IRSA authentication, leave `accessKey` and `secretKey` empty.

If you are using an IAM user instead, set:
- `accessKey` to the IAM user's access key ID
- `secretKey` to the IAM user's secret access key

That IAM user must have permission to read the target secret from AWS Secrets Manager:

```json
{
 "Version": "2012-10-17",
 "Statement": [
 {
 "Effect": "Allow",
 "Action": [
 "secretsmanager:GetSecretValue",
 "secretsmanager:DescribeSecret"
 ],
 "Resource": "arn:aws:secretsmanager:<region>:<account-id>:secret:<secret-name>*"
 }
 ]
}
```

:::note
Include the trailing `*` in the secret ARN. AWS appends a random suffix to secret names in the ARN, so omitting it can cause access failures.
:::

</TabItem>
<TabItem value="azure-key-vault" label="Azure Key Vault">

 1. Locate the `secretstore` attribute in `values.yaml`.
 2. Add Azure Key Vault configuration. For more information, see [Azure Key Vault secret store](https://docs.dapr.io/reference/components-reference/supported-secret-stores/azure-keyvault/)

 ```yaml
 secretstore:
 enabled: true
 spec:
 type: secretstores.azure.keyvault
 version: v1
 metadata:
 - name: vaultName
 value: "<your-keyvault-name>"
 - name: azureTenantId
 value: "<your-tenant-id>"
 - name: azureClientId
 value: "<your-client-id>"
 - name: azureClientSecret
 value: "<your-client-secret>"
 - name: azureEnvironment
 value: "AZUREPUBLICCLOUD" # Optional: AZUREPUBLICCLOUD, AZURECHINACLOUD, AZUREUSGOVERNMENTCLOUD, AZUREGERMANCLOUD
 ```
 Azure Key Vault supports multiple authentication methods:
 - **Client Secret**: Use `azureClientSecret` with tenant ID and client ID
 - **Certificate**: Use `azureCertificateFile` instead of client secret
 - **Managed Identity**: Omit authentication fields and use Azure managed identity

 For detailed authentication setup, see the [Authenticating to Azure](https://docs.dapr.io/developing-applications/integrations/azure/azure-authentication/authenticating-azure/) documentation.

</TabItem>
<TabItem value="gcp-secret-manager" label="GCP Secret Manager">

1. Locate the `secretstore` attribute in `values.yaml`.
2. Add Google Cloud Secret Manager configuration. For more information, see [GCP Secret Manager](https://docs.dapr.io/reference/components-reference/supported-secret-stores/gcp-secret-manager/)

 The GCP service account used in this configuration must have the `Secret Manager Secret Accessor` role (`roles/secretmanager.secretAccessor`) on the project where your secrets are stored. The metadata values below come from the service account's JSON key file.

 ```yaml
 secretstore:
 enabled: true
 spec:
 type: secretstores.gcp.secretmanager
 version: v1
 metadata:
 - name: type
 value: "service_account"
 - name: project_id
 value: "<project-id>"
 - name: private_key_id
 value: "<private-key-id>"
 - name: private_key
 value: "<private-key>"
 - name: client_email
 value: "<client-email>"
 - name: client_id
 value: "<client-id>"
 - name: auth_uri
 value: "https://accounts.google.com/o/oauth2/auth"
 - name: token_uri
 value: "https://oauth2.googleapis.com/token"
 - name: auth_provider_x509_cert_url
 value: "https://www.googleapis.com/oauth2/v1/certs"
 - name: client_x509_cert_url
 value: "https://www.googleapis.com/robot/v1/metadata/x509/<client-email>"
 ```

</TabItem>
<TabItem value="hashicorp-vault" label="HashiCorp Vault">

1. Locate the `secretstore` attribute in `values.yaml`.
2. Add HashiCorp Vault configuration. For more information, see [HashiCorp Vault](https://docs.dapr.io/reference/components-reference/supported-secret-stores/hashicorp-vault/)

 ```yaml
 secretstore:
 enabled: true
 spec:
 type: secretstores.hashicorp.vault
 version: v1
 metadata:
 - name: vaultAddr
 value: "[vault_address]" # Optional. Default: "https://127.0.0.1:8200"
 - name: caCert # Optional. This or caPath or caPem
 value: "[ca_cert]"
 - name: caPath # Optional. This or CaCert or caPem
 value: "[path_to_ca_cert_file]"
 - name: caPem # Optional. This or CaCert or CaPath
 value: "[encoded_ca_cert_pem]"
 - name: skipVerify # Optional. Default: false
 value: "[skip_tls_verification]"
 - name: tlsServerName # Optional.
 value: "[tls_config_server_name]"
 - name: vaultTokenMountPath # Required if vaultToken not provided. Path to token file.
 value: "[path_to_file_containing_token]"
 - name: vaultToken # Required if vaultTokenMountPath not provided. Token value.
 value: "[vault_token]"
 - name: vaultKVPrefix # Optional. Default: "dapr"
 value: "[vault_prefix]"
 - name: vaultKVUsePrefix # Optional. default: "true"
 value: "[true/false]"
 - name: enginePath # Optional. default: "secret"
 value: "secret"
 - name: vaultValueType # Optional. default: "map"
 value: "map"
 ```

</TabItem>
<TabItem value="kubernetes-secrets" label="Kubernetes Secrets">

1. Locate the `secretstore` attribute in `values.yaml`.
2. Add Kubernetes native secret storage. For more information, see [Kubernetes secrets](https://docs.dapr.io/reference/components-reference/supported-secret-stores/kubernetes-secret-store/)

 ```yaml
 secretstore:
 enabled: true
 spec:
 type: secretstores.kubernetes
 version: v1
 metadata:
 - name: defaultNamespace
 value: "default" # Optional: Default namespace to retrieve secrets from
 - name: kubeconfigPath
 value: "/path/to/kubeconfig" # Optional: Path to kubeconfig file
 ```
 When Dapr is deployed to a Kubernetes cluster, a secret store with the name `kubernetes` is automatically provisioned. You can use this native Kubernetes secret store with no need to create, deploy or maintain a component configuration file.

</TabItem>
<TabItem value="environment-variable-based" label="Environment Variables">

1. Locate the `secretstore` attribute in `values.yaml`.
2. Add Local environment variables as the spec. For more information, see [Local Environment Variables](https://docs.dapr.io/reference/components-reference/supported-secret-stores/envvar-secret-store/)

 ```yaml
 secretstore:
 enabled: true
 spec:
 type: secretstores.local.env
 version: v1
 ```

</TabItem>
</Tabs>

### Image source

Choose how the cluster pulls the app image. Most installs use Atlan's Docker Hub directly; mirror to a private registry if your organization requires it.

<Tabs>
<TabItem value="docker-hub" label="Public Docker Hub" default>

The chart pulls the app image from Atlan's Docker Hub at runtime. The pod needs a Kubernetes secret containing your Docker Hub PAT to authenticate:

```bash
kubectl create secret docker-registry atlan-docker-secret \
 --docker-server=docker.io \
 --docker-username=YOUR_USERNAME \
 --docker-password=YOUR_PAT_TOKEN \
 -n <namespace>
```

- Replace `YOUR_USERNAME` with the Docker Hub username provided by Atlan.
- Replace `YOUR_PAT_TOKEN` with the Personal Access Token (PAT) provided by Atlan.
- Replace `<namespace>` with the namespace you need to install the chart into. The secret and the release must live in the same namespace, or the pod fails with `ImagePullBackOff`.

The downloaded `values.yaml` already references this secret under `imagePullSecrets`. If you use a different secret name, update that field in the file.

</TabItem>
<TabItem value="private-registry" label="Private image repo">

Mirror the Atlan image to your enterprise registry and update `values.yaml` to point at it.

1. Authenticate with Docker Hub using the PAT from Atlan, then pull the source image. The image and tag come from `image.repository` and `image.tag` in the downloaded `values.yaml`:

 ```bash
 docker login -u atlanhq
 # When prompted for password, enter the PAT provided by Atlan
 docker pull <image.repository>:<image.tag>
 ```

2. Push the image to your enterprise's registry. Note down the new repository name and image tag.

3. Update `image.repository` and `image.tag` in `values.yaml` with the new values.

4. If your private registry requires authentication, create an image-pull secret in the target namespace and set `imagePullSecrets` in `values.yaml` to its name.

</TabItem>
</Tabs>

<h2 id="deploy-app">Deploy app</h2>

Follow these steps to deploy the secure app:

* Install the helm chart. The chart directory now carries your edited `values.yaml`, so no `-f` flag is needed:

 ```bash
 helm install {{deploymentValues.helmChartName}}-release ./{{deploymentValues.helmChartName}} -n <namespace>
 ```

 - Replace `<namespace>` with your target Kubernetes namespace.
 - The helm chart name `{{deploymentValues.helmChartName}}` is automatically used from your selected app.

The deployment process typically takes a few minutes to complete depending on factors like Kubernetes cluster resource availability, private image repository download time etc.

<h2 id="verify-app">Verify app</h2>

Follow these steps to verify deployment:

### Verify deployment status on cluster

1. Check pod status:

 ```bash
 kubectl get pods -n <namespace>
 ```

 The output appears similar to:

 ```
 NAME READY STATUS RESTARTS AGE
 <helm-chart-name>-release-<helm-chart-name>-5dff95cd85-cvk5z 1/1 Running 0 2m
 ```
 
 Replace `<helm-chart-name>` with your app's helm chart name (shown in the prerequisites section earlier in this guide).

 The pod status shows `Running` with `1/1` ready containers.

2. Verify logs for the running pod
 
 ```bash
 kubectl logs -n <namespace> -l app.kubernetes.io/name={{deploymentValues.helmChartName}} --tail=50 -f
 ```
 **Example application logs**: Look for these key log messages that confirm successful deployment:

 * `Uvicorn running on http://0.0.0.0:8000` - Web server started
 * `Workflow engine initialized` - Workflow processing ready
 * `dapr initialized. Status: Running` - Dapr runtime active
 * `Starting worker with task queue: atlan-<package-name>-DEPLOYMENT_NAME` - Worker process started (replace `<package-name>` with your app's package name)
 * `GET /server/ready 200` - Health check endpoint responding

### Verify registration via Atlan UI

Once the App is successfully deployed, it communicates to the Atlan tenant and registers itself. Verify App registration is successful in Atlan:

1. In the same Atlan tenant, navigate to **Workflows** > **Agent**.
2. Look for an entry named `<app_name>-<deployment_name>`, where `<app_name>` matches your selected app (for example, "Oracle" or "Microsoft SQL Server") and `<deployment_name>` is the deployment name you entered when generating the config.
3. Confirm the agent status displays as **Active**.

Agent registration and status takes a couple of minutes to reflect in the Atlan UI.

<h2 id="next-steps">Next steps</h2>

* [Configure workflow execution](https://docs.atlan.com/product/connections/self-deployed-runtime/how-tos/configure-workflow-execution): Set up workflow execution with secret retrieval for your Self-deployed Runtime

---

## Install on Kubernetes - Google BigQuery

URL: https://docs.atlan.com/product/connections/self-deployed-runtime/how-tos/install-on-kubernetes
**Connector:** Google BigQuery (data-warehouse)

> Install an App on Kubernetes using Helm charts, Docker images, and specific configuration

:::info **Did you know?** 
SDR requires additional enablement and licensing. Contact your Atlan representative for details.
:::

:::warning Use the guided install wizard instead
**New Self-Deployed Runtime setups are encouraged to use the [guided install wizard](https://docs.atlan.com/product/connections/self-deployed-runtime/how-tos/install-guided).** It assembles a complete guide tailored to your lifecycle mode, platform, and image procurement on a single page—and it's where new setup options (for example, HTTP proxy and custom CA trust) are documented going forward.

This page is kept for existing users who already reference it and may not include the latest steps.
:::

<h2 id="prerequisites">Prerequisites</h2>

Before you begin, make sure you have:

* `kubectl` installed and configured with administrative access to your target Kubernetes cluster
* Helm version 3.0 or later installed on your deployment machine
* A [Docker Hub Personal Access Token (PAT)](https://start.1password.com/open/i?a=WAVUZSKJO5GMNMVBYWAWECXIUE&v=ouvp3xf5334cxoamyiipzjlewy&i=p76avgzmkkcbftldcuvr5jcof4&h=atlanhq.1password.com) from Atlan
* App-specific helm chart name: `{{deploymentValues.helmChartName}}` 
* Object storage: AWS S3, Google Cloud Storage, or Azure Blob Storage with read/write permissions
* Secret store access: AWS Secret Manager, Azure Key Vault, GCP Secret Manager, HashiCorp Vault, or Kubernetes Secrets with read permissions

:::warning For security reasons, the Docker Hub PAT Token is regenerated on a periodic basis. 
In case the token is embedded in automation scripts or CI/CD pipelines, those jobs may fail. 
Contact your Atlan representative for the latest token.
:::

<h2 id="download-required-files">Download required files</h2>

<h3 id="download-helm-chart">Download Helm chart</h3>

Download the Helm chart for the app:

```bash
helm pull oci://registry-1.docker.io/atlanhq/{{deploymentValues.helmChartName}} --untar
```

This unpacks the chart's `Chart.yaml`, `templates/`, and a default `values.yaml` into `./{{deploymentValues.helmChartName}}/`. You'll replace this default `values.yaml` with your Marketplace copy in the next step.

<h3 id="download-values-yaml">Download values.yaml</h3>

Atlan generates the helm `values.yaml` for your runtime directly from the Marketplace UI, including the OAuth client credentials your runtime uses to authenticate to your tenant.

1. Sign in to your Atlan tenant as an administrator, open **Connector** > **Marketplace**, select the app you want to deploy, and click **Download config for Self-Deployed Runtime** in the right-hand sidebar.

2. In the dialog, keep **New deployment** selected (this mints the OAuth client and full config for a fresh runtime), choose **Kubernetes (Helm)** as the deployment target, and enter a **Deployment name**: a short identifier (lowercase letters, digits, and dashes) that identifies this runtime; the agent in **Workflows > Agent** is named `<app_name>-<deployment_name>`.

3. Click **Generate**. Atlan mints a dedicated OAuth client and produces a `values.yaml` file with:
 - `global.atlanBaseUrl`, `global.clientId`, and `global.clientSecret` already filled in.
 - `image.repository`, `image.tag`, and `name` pinned to the active version for your tenant.
 - `objectstore` and `secretstore` placeholders for you to configure below.

<h3 id="replace-chart-values">Replace chart values.yaml</h3>

Replace the default `values.yaml` inside the unpacked chart with the `values.yaml` you downloaded from the Marketplace.

From this point on, all edits to `values.yaml` must be made inside `./{{deploymentValues.helmChartName}}/`.

<h2 id="modify-values-yaml">Modify values.yaml</h2>

### Object storage

Self-Deployed Runtime needs a store for reading or writing files. Configure the object storage that matches your environment:

:::tip Don't see your preferred object store?
If your preferred object store isn't listed here, [reach out to Atlan support](https://docs.atlan.com/support/submit-request). Support for additional object stores may be available.
:::

<Tabs>
<TabItem value="aws-s3" label="AWS S3" default>

**Required permissions:**

Apply object-level actions to `arn:aws:s3:::BUCKET/*` and the list action to `arn:aws:s3:::BUCKET` in separate IAM statement entries.

| IAM action | Operations covered |
|---|---|
| `s3:GetObject` | GetObject (full and byte-range), HeadObject |
| `s3:PutObject` | PutObject, CreateMultipartUpload, UploadPart, CompleteMultipartUpload |
| `s3:AbortMultipartUpload` | Abort in-flight multipart upload on error (required for streaming write error paths) |
| `s3:DeleteObject` | DeleteObject and DeleteObjects (bulk batch—same IAM action) |
| `s3:ListBucket` | ListObjectsV2—bucket-level permission, not object-level |

```json
{
 "Version": "2012-10-17",
 "Statement": [
 {
 "Effect": "Allow",
 "Action": [
 "s3:GetObject",
 "s3:PutObject",
 "s3:AbortMultipartUpload",
 "s3:DeleteObject"
 ],
 "Resource": "arn:aws:s3:::YOUR-BUCKET/*"
 },
 {
 "Effect": "Allow",
 "Action": "s3:ListBucket",
 "Resource": "arn:aws:s3:::YOUR-BUCKET"
 }
 ]
}
```

**AssumeRole**: when using `assumeRoleArn`, the caller identity additionally needs `sts:AssumeRole` on the target role ARN. The role itself holds the bucket policy described earlier.

**Configure:**

 1. Locate the `objectstore` attribute in `values.yaml`.
 2. Add AWS S3 configuration. For more information, see [AWS S3 Binding Spec](https://docs.dapr.io/reference/components-reference/supported-bindings/s3/).

 ```yaml
 objectstore:
 enabled: true
 spec:
 type: bindings.aws.s3
 version: v1
 metadata:
 - name: accessKey #optional, leave this empty for iam authentication
 value: ""
 - name: secretKey #optional, leave this empty for iam authentication
 value: ""
 - name: bucket #required, name of the bucket where application can write
 value: "<bucket-name>"
 - name: region #required, region of the bucket where application can write
 value: "<bucket-region>"
 - name: forcePathStyle
 value: "true"
 ```

</TabItem>
<TabItem value="gcp-storage" label="Google Cloud Storage">

**Required permissions:**

| IAM permission | Operations covered |
|---|---|
| `storage.objects.get` | GetObject (full and byte-range), object metadata / HeadObject equivalent |
| `storage.objects.create` | PutObject, resumable / streaming write |
| `storage.objects.delete` | DeleteObject (GCS has no native bulk-delete API—`delete_prefix` issues parallel single-object deletes) |
| `storage.objects.list` | ListObjects |

No `storage.buckets.*` permissions are needed. The smallest predefined role that covers all four is **`roles/storage.objectAdmin`** scoped to the bucket. Alternatively, create a custom role with exactly these four permissions.

**Configure:**

 1. Locate the `objectstore` attribute in `values.yaml`.
 2. Add Google Cloud Storage configuration. For more information, see [GCP Storage Bucket binding spec](https://docs.dapr.io/reference/components-reference/supported-bindings/gcpbucket/)

 ```yaml
 objectstore:
 enabled: true
 spec:
 type: bindings.gcp.bucket
 version: v1
 metadata:
 - name: bucket
 value: "your-gcs-bucket-name"
 - name: type
 value: "service_account"
 - name: project_id
 value: "your-gcp-project-id"
 ```

</TabItem>
<TabItem value="azure-blob" label="Azure Blob Storage">

**Required permissions:**

**RBAC**—assign at container or storage-account scope:

| RBAC action | Operations covered |
|---|---|
| `Microsoft.Storage/storageAccounts/blobServices/containers/blobs/read` | GetBlob, GetBlobProperties (HEAD), ListBlobs, byte-range GET |
| `Microsoft.Storage/storageAccounts/blobServices/containers/blobs/write` | PutBlob, PutBlock + PutBlockList (streaming / block write) |
| `Microsoft.Storage/storageAccounts/blobServices/containers/blobs/delete` | DeleteBlob, BlobBatch delete (bulk—up to 256 keys per request) |

The smallest predefined role covering all three is **`Storage Blob Data Contributor`**. `Storage Blob Data Owner` is a superset and is only needed if you additionally require POSIX ACL management on ADLS Gen2.

**SAS token**—minimum permissions at container scope: `r` (read) + `w` (write) + `d` (delete) + `l` (list), that is a container-scoped SAS with **`rwdl`**.

**ADLS Gen2 with POSIX ACLs**: if the storage account has hierarchical namespace enabled and you use ACL-based access control instead of RBAC, the principal needs Execute (`X`) on every parent directory and Read / Write / Delete on the objects in scope. RBAC (`Storage Blob Data Contributor`) is simpler and is recommended unless you have a specific ACL requirement.

**Configure:**

 1. Locate the `objectstore` attribute in `values.yaml`.
 2. Add Azure Blob Storage configuration. For more information, see [Azure Blob Storage binding spec](https://docs.dapr.io/reference/components-reference/supported-bindings/blobstorage/)

 ```yaml
 objectstore:
 enabled: true
 spec:
 type: bindings.azure.blobstorage
 version: v1
 metadata:
 - name: accountName
 value: "your-storage-account-name"
 - name: accountKey
 value: "your-storage-account-key"
 - name: containerName
 value: "your-container-name"
 ```

</TabItem>
</Tabs>

### Secret storage

Self-Deployed Runtime fetches secrets from a secret store to connect to the source systems. The secret store references are used to configure the workflow. Configure the secret store that aligns with your security infrastructure:

:::info Did you know?
Dapr supports additional secret stores which aren't mentioned here. For more information, see [Dapr secret store documentation](https://docs.dapr.io/reference/components-reference/supported-secret-stores/) for other configurations.
:::

:::warning Secret content format and naming
When storing credentials, follow the [secret naming and format requirements](https://docs.atlan.com/product/connections/self-deployed-runtime/how-tos/configure-workflow-execution#secret-content-format).
:::

<Tabs>
<TabItem value="aws-secret-manager" label="AWS Secret Manager" default>
 
 1. Locate the `secretstore` attribute in `values.yaml`.
 2. Add AWS Secret Manager configuration. For more information, see [AWS Secrets Manager](https://docs.dapr.io/reference/components-reference/supported-secret-stores/aws-secret-manager/)

 ```yaml
 secretstore:
 enabled: true
 spec:
 type: secretstores.aws.secretmanager
 version: v1
 metadata:
 - name: region # required, region in which secret is hosted
 value: <secret-region>
 # Needed if IAM authentication is not used
 - name: accessKey
 value: ""
 - name: secretKey
 value: ""
 ```

If you are using IAM role / IRSA authentication, leave `accessKey` and `secretKey` empty.

If you are using an IAM user instead, set:
- `accessKey` to the IAM user's access key ID
- `secretKey` to the IAM user's secret access key

That IAM user must have permission to read the target secret from AWS Secrets Manager:

```json
{
 "Version": "2012-10-17",
 "Statement": [
 {
 "Effect": "Allow",
 "Action": [
 "secretsmanager:GetSecretValue",
 "secretsmanager:DescribeSecret"
 ],
 "Resource": "arn:aws:secretsmanager:<region>:<account-id>:secret:<secret-name>*"
 }
 ]
}
```

:::note
Include the trailing `*` in the secret ARN. AWS appends a random suffix to secret names in the ARN, so omitting it can cause access failures.
:::

</TabItem>
<TabItem value="azure-key-vault" label="Azure Key Vault">

 1. Locate the `secretstore` attribute in `values.yaml`.
 2. Add Azure Key Vault configuration. For more information, see [Azure Key Vault secret store](https://docs.dapr.io/reference/components-reference/supported-secret-stores/azure-keyvault/)

 ```yaml
 secretstore:
 enabled: true
 spec:
 type: secretstores.azure.keyvault
 version: v1
 metadata:
 - name: vaultName
 value: "<your-keyvault-name>"
 - name: azureTenantId
 value: "<your-tenant-id>"
 - name: azureClientId
 value: "<your-client-id>"
 - name: azureClientSecret
 value: "<your-client-secret>"
 - name: azureEnvironment
 value: "AZUREPUBLICCLOUD" # Optional: AZUREPUBLICCLOUD, AZURECHINACLOUD, AZUREUSGOVERNMENTCLOUD, AZUREGERMANCLOUD
 ```
 Azure Key Vault supports multiple authentication methods:
 - **Client Secret**: Use `azureClientSecret` with tenant ID and client ID
 - **Certificate**: Use `azureCertificateFile` instead of client secret
 - **Managed Identity**: Omit authentication fields and use Azure managed identity

 For detailed authentication setup, see the [Authenticating to Azure](https://docs.dapr.io/developing-applications/integrations/azure/azure-authentication/authenticating-azure/) documentation.

</TabItem>
<TabItem value="gcp-secret-manager" label="GCP Secret Manager">

1. Locate the `secretstore` attribute in `values.yaml`.
2. Add Google Cloud Secret Manager configuration. For more information, see [GCP Secret Manager](https://docs.dapr.io/reference/components-reference/supported-secret-stores/gcp-secret-manager/)

 The GCP service account used in this configuration must have the `Secret Manager Secret Accessor` role (`roles/secretmanager.secretAccessor`) on the project where your secrets are stored. The metadata values below come from the service account's JSON key file.

 ```yaml
 secretstore:
 enabled: true
 spec:
 type: secretstores.gcp.secretmanager
 version: v1
 metadata:
 - name: type
 value: "service_account"
 - name: project_id
 value: "<project-id>"
 - name: private_key_id
 value: "<private-key-id>"
 - name: private_key
 value: "<private-key>"
 - name: client_email
 value: "<client-email>"
 - name: client_id
 value: "<client-id>"
 - name: auth_uri
 value: "https://accounts.google.com/o/oauth2/auth"
 - name: token_uri
 value: "https://oauth2.googleapis.com/token"
 - name: auth_provider_x509_cert_url
 value: "https://www.googleapis.com/oauth2/v1/certs"
 - name: client_x509_cert_url
 value: "https://www.googleapis.com/robot/v1/metadata/x509/<client-email>"
 ```

</TabItem>
<TabItem value="hashicorp-vault" label="HashiCorp Vault">

1. Locate the `secretstore` attribute in `values.yaml`.
2. Add HashiCorp Vault configuration. For more information, see [HashiCorp Vault](https://docs.dapr.io/reference/components-reference/supported-secret-stores/hashicorp-vault/)

 ```yaml
 secretstore:
 enabled: true
 spec:
 type: secretstores.hashicorp.vault
 version: v1
 metadata:
 - name: vaultAddr
 value: "[vault_address]" # Optional. Default: "https://127.0.0.1:8200"
 - name: caCert # Optional. This or caPath or caPem
 value: "[ca_cert]"
 - name: caPath # Optional. This or CaCert or caPem
 value: "[path_to_ca_cert_file]"
 - name: caPem # Optional. This or CaCert or CaPath
 value: "[encoded_ca_cert_pem]"
 - name: skipVerify # Optional. Default: false
 value: "[skip_tls_verification]"
 - name: tlsServerName # Optional.
 value: "[tls_config_server_name]"
 - name: vaultTokenMountPath # Required if vaultToken not provided. Path to token file.
 value: "[path_to_file_containing_token]"
 - name: vaultToken # Required if vaultTokenMountPath not provided. Token value.
 value: "[vault_token]"
 - name: vaultKVPrefix # Optional. Default: "dapr"
 value: "[vault_prefix]"
 - name: vaultKVUsePrefix # Optional. default: "true"
 value: "[true/false]"
 - name: enginePath # Optional. default: "secret"
 value: "secret"
 - name: vaultValueType # Optional. default: "map"
 value: "map"
 ```

</TabItem>
<TabItem value="kubernetes-secrets" label="Kubernetes Secrets">

1. Locate the `secretstore` attribute in `values.yaml`.
2. Add Kubernetes native secret storage. For more information, see [Kubernetes secrets](https://docs.dapr.io/reference/components-reference/supported-secret-stores/kubernetes-secret-store/)

 ```yaml
 secretstore:
 enabled: true
 spec:
 type: secretstores.kubernetes
 version: v1
 metadata:
 - name: defaultNamespace
 value: "default" # Optional: Default namespace to retrieve secrets from
 - name: kubeconfigPath
 value: "/path/to/kubeconfig" # Optional: Path to kubeconfig file
 ```
 When Dapr is deployed to a Kubernetes cluster, a secret store with the name `kubernetes` is automatically provisioned. You can use this native Kubernetes secret store with no need to create, deploy or maintain a component configuration file.

</TabItem>
<TabItem value="environment-variable-based" label="Environment Variables">

1. Locate the `secretstore` attribute in `values.yaml`.
2. Add Local environment variables as the spec. For more information, see [Local Environment Variables](https://docs.dapr.io/reference/components-reference/supported-secret-stores/envvar-secret-store/)

 ```yaml
 secretstore:
 enabled: true
 spec:
 type: secretstores.local.env
 version: v1
 ```

</TabItem>
</Tabs>

### Image source

Choose how the cluster pulls the app image. Most installs use Atlan's Docker Hub directly; mirror to a private registry if your organization requires it.

<Tabs>
<TabItem value="docker-hub" label="Public Docker Hub" default>

The chart pulls the app image from Atlan's Docker Hub at runtime. The pod needs a Kubernetes secret containing your Docker Hub PAT to authenticate:

```bash
kubectl create secret docker-registry atlan-docker-secret \
 --docker-server=docker.io \
 --docker-username=YOUR_USERNAME \
 --docker-password=YOUR_PAT_TOKEN \
 -n <namespace>
```

- Replace `YOUR_USERNAME` with the Docker Hub username provided by Atlan.
- Replace `YOUR_PAT_TOKEN` with the Personal Access Token (PAT) provided by Atlan.
- Replace `<namespace>` with the namespace you need to install the chart into. The secret and the release must live in the same namespace, or the pod fails with `ImagePullBackOff`.

The downloaded `values.yaml` already references this secret under `imagePullSecrets`. If you use a different secret name, update that field in the file.

</TabItem>
<TabItem value="private-registry" label="Private image repo">

Mirror the Atlan image to your enterprise registry and update `values.yaml` to point at it.

1. Authenticate with Docker Hub using the PAT from Atlan, then pull the source image. The image and tag come from `image.repository` and `image.tag` in the downloaded `values.yaml`:

 ```bash
 docker login -u atlanhq
 # When prompted for password, enter the PAT provided by Atlan
 docker pull <image.repository>:<image.tag>
 ```

2. Push the image to your enterprise's registry. Note down the new repository name and image tag.

3. Update `image.repository` and `image.tag` in `values.yaml` with the new values.

4. If your private registry requires authentication, create an image-pull secret in the target namespace and set `imagePullSecrets` in `values.yaml` to its name.

</TabItem>
</Tabs>

<h2 id="deploy-app">Deploy app</h2>

Follow these steps to deploy the secure app:

* Install the helm chart. The chart directory now carries your edited `values.yaml`, so no `-f` flag is needed:

 ```bash
 helm install {{deploymentValues.helmChartName}}-release ./{{deploymentValues.helmChartName}} -n <namespace>
 ```

 - Replace `<namespace>` with your target Kubernetes namespace.
 - The helm chart name `{{deploymentValues.helmChartName}}` is automatically used from your selected app.

The deployment process typically takes a few minutes to complete depending on factors like Kubernetes cluster resource availability, private image repository download time etc.

<h2 id="verify-app">Verify app</h2>

Follow these steps to verify deployment:

### Verify deployment status on cluster

1. Check pod status:

 ```bash
 kubectl get pods -n <namespace>
 ```

 The output appears similar to:

 ```
 NAME READY STATUS RESTARTS AGE
 <helm-chart-name>-release-<helm-chart-name>-5dff95cd85-cvk5z 1/1 Running 0 2m
 ```
 
 Replace `<helm-chart-name>` with your app's helm chart name (shown in the prerequisites section earlier in this guide).

 The pod status shows `Running` with `1/1` ready containers.

2. Verify logs for the running pod
 
 ```bash
 kubectl logs -n <namespace> -l app.kubernetes.io/name={{deploymentValues.helmChartName}} --tail=50 -f
 ```
 **Example application logs**: Look for these key log messages that confirm successful deployment:

 * `Uvicorn running on http://0.0.0.0:8000` - Web server started
 * `Workflow engine initialized` - Workflow processing ready
 * `dapr initialized. Status: Running` - Dapr runtime active
 * `Starting worker with task queue: atlan-<package-name>-DEPLOYMENT_NAME` - Worker process started (replace `<package-name>` with your app's package name)
 * `GET /server/ready 200` - Health check endpoint responding

### Verify registration via Atlan UI

Once the App is successfully deployed, it communicates to the Atlan tenant and registers itself. Verify App registration is successful in Atlan:

1. In the same Atlan tenant, navigate to **Workflows** > **Agent**.
2. Look for an entry named `<app_name>-<deployment_name>`, where `<app_name>` matches your selected app (for example, "Oracle" or "Microsoft SQL Server") and `<deployment_name>` is the deployment name you entered when generating the config.
3. Confirm the agent status displays as **Active**.

Agent registration and status takes a couple of minutes to reflect in the Atlan UI.

<h2 id="next-steps">Next steps</h2>

* [Configure workflow execution](https://docs.atlan.com/product/connections/self-deployed-runtime/how-tos/configure-workflow-execution): Set up workflow execution with secret retrieval for your Self-deployed Runtime

---

## Install on Kubernetes - SAP Datasphere

URL: https://docs.atlan.com/product/connections/self-deployed-runtime/how-tos/install-on-kubernetes
**Connector:** SAP Datasphere (data-warehouse)

> Install an App on Kubernetes using Helm charts, Docker images, and specific configuration

:::info **Did you know?** 
SDR requires additional enablement and licensing. Contact your Atlan representative for details.
:::

:::warning Use the guided install wizard instead
**New Self-Deployed Runtime setups are encouraged to use the [guided install wizard](https://docs.atlan.com/product/connections/self-deployed-runtime/how-tos/install-guided).** It assembles a complete guide tailored to your lifecycle mode, platform, and image procurement on a single page—and it's where new setup options (for example, HTTP proxy and custom CA trust) are documented going forward.

This page is kept for existing users who already reference it and may not include the latest steps.
:::

<h2 id="prerequisites">Prerequisites</h2>

Before you begin, make sure you have:

* `kubectl` installed and configured with administrative access to your target Kubernetes cluster
* Helm version 3.0 or later installed on your deployment machine
* A [Docker Hub Personal Access Token (PAT)](https://start.1password.com/open/i?a=WAVUZSKJO5GMNMVBYWAWECXIUE&v=ouvp3xf5334cxoamyiipzjlewy&i=p76avgzmkkcbftldcuvr5jcof4&h=atlanhq.1password.com) from Atlan
* App-specific helm chart name: `{{deploymentValues.helmChartName}}` 
* Object storage: AWS S3, Google Cloud Storage, or Azure Blob Storage with read/write permissions
* Secret store access: AWS Secret Manager, Azure Key Vault, GCP Secret Manager, HashiCorp Vault, or Kubernetes Secrets with read permissions

:::warning For security reasons, the Docker Hub PAT Token is regenerated on a periodic basis. 
In case the token is embedded in automation scripts or CI/CD pipelines, those jobs may fail. 
Contact your Atlan representative for the latest token.
:::

<h2 id="download-required-files">Download required files</h2>

<h3 id="download-helm-chart">Download Helm chart</h3>

Download the Helm chart for the app:

```bash
helm pull oci://registry-1.docker.io/atlanhq/{{deploymentValues.helmChartName}} --untar
```

This unpacks the chart's `Chart.yaml`, `templates/`, and a default `values.yaml` into `./{{deploymentValues.helmChartName}}/`. You'll replace this default `values.yaml` with your Marketplace copy in the next step.

<h3 id="download-values-yaml">Download values.yaml</h3>

Atlan generates the helm `values.yaml` for your runtime directly from the Marketplace UI, including the OAuth client credentials your runtime uses to authenticate to your tenant.

1. Sign in to your Atlan tenant as an administrator, open **Connector** > **Marketplace**, select the app you want to deploy, and click **Download config for Self-Deployed Runtime** in the right-hand sidebar.

2. In the dialog, keep **New deployment** selected (this mints the OAuth client and full config for a fresh runtime), choose **Kubernetes (Helm)** as the deployment target, and enter a **Deployment name**: a short identifier (lowercase letters, digits, and dashes) that identifies this runtime; the agent in **Workflows > Agent** is named `<app_name>-<deployment_name>`.

3. Click **Generate**. Atlan mints a dedicated OAuth client and produces a `values.yaml` file with:
 - `global.atlanBaseUrl`, `global.clientId`, and `global.clientSecret` already filled in.
 - `image.repository`, `image.tag`, and `name` pinned to the active version for your tenant.
 - `objectstore` and `secretstore` placeholders for you to configure below.

<h3 id="replace-chart-values">Replace chart values.yaml</h3>

Replace the default `values.yaml` inside the unpacked chart with the `values.yaml` you downloaded from the Marketplace.

From this point on, all edits to `values.yaml` must be made inside `./{{deploymentValues.helmChartName}}/`.

<h2 id="modify-values-yaml">Modify values.yaml</h2>

### Object storage

Self-Deployed Runtime needs a store for reading or writing files. Configure the object storage that matches your environment:

:::tip Don't see your preferred object store?
If your preferred object store isn't listed here, [reach out to Atlan support](https://docs.atlan.com/support/submit-request). Support for additional object stores may be available.
:::

<Tabs>
<TabItem value="aws-s3" label="AWS S3" default>

**Required permissions:**

Apply object-level actions to `arn:aws:s3:::BUCKET/*` and the list action to `arn:aws:s3:::BUCKET` in separate IAM statement entries.

| IAM action | Operations covered |
|---|---|
| `s3:GetObject` | GetObject (full and byte-range), HeadObject |
| `s3:PutObject` | PutObject, CreateMultipartUpload, UploadPart, CompleteMultipartUpload |
| `s3:AbortMultipartUpload` | Abort in-flight multipart upload on error (required for streaming write error paths) |
| `s3:DeleteObject` | DeleteObject and DeleteObjects (bulk batch—same IAM action) |
| `s3:ListBucket` | ListObjectsV2—bucket-level permission, not object-level |

```json
{
 "Version": "2012-10-17",
 "Statement": [
 {
 "Effect": "Allow",
 "Action": [
 "s3:GetObject",
 "s3:PutObject",
 "s3:AbortMultipartUpload",
 "s3:DeleteObject"
 ],
 "Resource": "arn:aws:s3:::YOUR-BUCKET/*"
 },
 {
 "Effect": "Allow",
 "Action": "s3:ListBucket",
 "Resource": "arn:aws:s3:::YOUR-BUCKET"
 }
 ]
}
```

**AssumeRole**: when using `assumeRoleArn`, the caller identity additionally needs `sts:AssumeRole` on the target role ARN. The role itself holds the bucket policy described earlier.

**Configure:**

 1. Locate the `objectstore` attribute in `values.yaml`.
 2. Add AWS S3 configuration. For more information, see [AWS S3 Binding Spec](https://docs.dapr.io/reference/components-reference/supported-bindings/s3/).

 ```yaml
 objectstore:
 enabled: true
 spec:
 type: bindings.aws.s3
 version: v1
 metadata:
 - name: accessKey #optional, leave this empty for iam authentication
 value: ""
 - name: secretKey #optional, leave this empty for iam authentication
 value: ""
 - name: bucket #required, name of the bucket where application can write
 value: "<bucket-name>"
 - name: region #required, region of the bucket where application can write
 value: "<bucket-region>"
 - name: forcePathStyle
 value: "true"
 ```

</TabItem>
<TabItem value="gcp-storage" label="Google Cloud Storage">

**Required permissions:**

| IAM permission | Operations covered |
|---|---|
| `storage.objects.get` | GetObject (full and byte-range), object metadata / HeadObject equivalent |
| `storage.objects.create` | PutObject, resumable / streaming write |
| `storage.objects.delete` | DeleteObject (GCS has no native bulk-delete API—`delete_prefix` issues parallel single-object deletes) |
| `storage.objects.list` | ListObjects |

No `storage.buckets.*` permissions are needed. The smallest predefined role that covers all four is **`roles/storage.objectAdmin`** scoped to the bucket. Alternatively, create a custom role with exactly these four permissions.

**Configure:**

 1. Locate the `objectstore` attribute in `values.yaml`.
 2. Add Google Cloud Storage configuration. For more information, see [GCP Storage Bucket binding spec](https://docs.dapr.io/reference/components-reference/supported-bindings/gcpbucket/)

 ```yaml
 objectstore:
 enabled: true
 spec:
 type: bindings.gcp.bucket
 version: v1
 metadata:
 - name: bucket
 value: "your-gcs-bucket-name"
 - name: type
 value: "service_account"
 - name: project_id
 value: "your-gcp-project-id"
 ```

</TabItem>
<TabItem value="azure-blob" label="Azure Blob Storage">

**Required permissions:**

**RBAC**—assign at container or storage-account scope:

| RBAC action | Operations covered |
|---|---|
| `Microsoft.Storage/storageAccounts/blobServices/containers/blobs/read` | GetBlob, GetBlobProperties (HEAD), ListBlobs, byte-range GET |
| `Microsoft.Storage/storageAccounts/blobServices/containers/blobs/write` | PutBlob, PutBlock + PutBlockList (streaming / block write) |
| `Microsoft.Storage/storageAccounts/blobServices/containers/blobs/delete` | DeleteBlob, BlobBatch delete (bulk—up to 256 keys per request) |

The smallest predefined role covering all three is **`Storage Blob Data Contributor`**. `Storage Blob Data Owner` is a superset and is only needed if you additionally require POSIX ACL management on ADLS Gen2.

**SAS token**—minimum permissions at container scope: `r` (read) + `w` (write) + `d` (delete) + `l` (list), that is a container-scoped SAS with **`rwdl`**.

**ADLS Gen2 with POSIX ACLs**: if the storage account has hierarchical namespace enabled and you use ACL-based access control instead of RBAC, the principal needs Execute (`X`) on every parent directory and Read / Write / Delete on the objects in scope. RBAC (`Storage Blob Data Contributor`) is simpler and is recommended unless you have a specific ACL requirement.

**Configure:**

 1. Locate the `objectstore` attribute in `values.yaml`.
 2. Add Azure Blob Storage configuration. For more information, see [Azure Blob Storage binding spec](https://docs.dapr.io/reference/components-reference/supported-bindings/blobstorage/)

 ```yaml
 objectstore:
 enabled: true
 spec:
 type: bindings.azure.blobstorage
 version: v1
 metadata:
 - name: accountName
 value: "your-storage-account-name"
 - name: accountKey
 value: "your-storage-account-key"
 - name: containerName
 value: "your-container-name"
 ```

</TabItem>
</Tabs>

### Secret storage

Self-Deployed Runtime fetches secrets from a secret store to connect to the source systems. The secret store references are used to configure the workflow. Configure the secret store that aligns with your security infrastructure:

:::info Did you know?
Dapr supports additional secret stores which aren't mentioned here. For more information, see [Dapr secret store documentation](https://docs.dapr.io/reference/components-reference/supported-secret-stores/) for other configurations.
:::

:::warning Secret content format and naming
When storing credentials, follow the [secret naming and format requirements](https://docs.atlan.com/product/connections/self-deployed-runtime/how-tos/configure-workflow-execution#secret-content-format).
:::

<Tabs>
<TabItem value="aws-secret-manager" label="AWS Secret Manager" default>
 
 1. Locate the `secretstore` attribute in `values.yaml`.
 2. Add AWS Secret Manager configuration. For more information, see [AWS Secrets Manager](https://docs.dapr.io/reference/components-reference/supported-secret-stores/aws-secret-manager/)

 ```yaml
 secretstore:
 enabled: true
 spec:
 type: secretstores.aws.secretmanager
 version: v1
 metadata:
 - name: region # required, region in which secret is hosted
 value: <secret-region>
 # Needed if IAM authentication is not used
 - name: accessKey
 value: ""
 - name: secretKey
 value: ""
 ```

If you are using IAM role / IRSA authentication, leave `accessKey` and `secretKey` empty.

If you are using an IAM user instead, set:
- `accessKey` to the IAM user's access key ID
- `secretKey` to the IAM user's secret access key

That IAM user must have permission to read the target secret from AWS Secrets Manager:

```json
{
 "Version": "2012-10-17",
 "Statement": [
 {
 "Effect": "Allow",
 "Action": [
 "secretsmanager:GetSecretValue",
 "secretsmanager:DescribeSecret"
 ],
 "Resource": "arn:aws:secretsmanager:<region>:<account-id>:secret:<secret-name>*"
 }
 ]
}
```

:::note
Include the trailing `*` in the secret ARN. AWS appends a random suffix to secret names in the ARN, so omitting it can cause access failures.
:::

</TabItem>
<TabItem value="azure-key-vault" label="Azure Key Vault">

 1. Locate the `secretstore` attribute in `values.yaml`.
 2. Add Azure Key Vault configuration. For more information, see [Azure Key Vault secret store](https://docs.dapr.io/reference/components-reference/supported-secret-stores/azure-keyvault/)

 ```yaml
 secretstore:
 enabled: true
 spec:
 type: secretstores.azure.keyvault
 version: v1
 metadata:
 - name: vaultName
 value: "<your-keyvault-name>"
 - name: azureTenantId
 value: "<your-tenant-id>"
 - name: azureClientId
 value: "<your-client-id>"
 - name: azureClientSecret
 value: "<your-client-secret>"
 - name: azureEnvironment
 value: "AZUREPUBLICCLOUD" # Optional: AZUREPUBLICCLOUD, AZURECHINACLOUD, AZUREUSGOVERNMENTCLOUD, AZUREGERMANCLOUD
 ```
 Azure Key Vault supports multiple authentication methods:
 - **Client Secret**: Use `azureClientSecret` with tenant ID and client ID
 - **Certificate**: Use `azureCertificateFile` instead of client secret
 - **Managed Identity**: Omit authentication fields and use Azure managed identity

 For detailed authentication setup, see the [Authenticating to Azure](https://docs.dapr.io/developing-applications/integrations/azure/azure-authentication/authenticating-azure/) documentation.

</TabItem>
<TabItem value="gcp-secret-manager" label="GCP Secret Manager">

1. Locate the `secretstore` attribute in `values.yaml`.
2. Add Google Cloud Secret Manager configuration. For more information, see [GCP Secret Manager](https://docs.dapr.io/reference/components-reference/supported-secret-stores/gcp-secret-manager/)

 The GCP service account used in this configuration must have the `Secret Manager Secret Accessor` role (`roles/secretmanager.secretAccessor`) on the project where your secrets are stored. The metadata values below come from the service account's JSON key file.

 ```yaml
 secretstore:
 enabled: true
 spec:
 type: secretstores.gcp.secretmanager
 version: v1
 metadata:
 - name: type
 value: "service_account"
 - name: project_id
 value: "<project-id>"
 - name: private_key_id
 value: "<private-key-id>"
 - name: private_key
 value: "<private-key>"
 - name: client_email
 value: "<client-email>"
 - name: client_id
 value: "<client-id>"
 - name: auth_uri
 value: "https://accounts.google.com/o/oauth2/auth"
 - name: token_uri
 value: "https://oauth2.googleapis.com/token"
 - name: auth_provider_x509_cert_url
 value: "https://www.googleapis.com/oauth2/v1/certs"
 - name: client_x509_cert_url
 value: "https://www.googleapis.com/robot/v1/metadata/x509/<client-email>"
 ```

</TabItem>
<TabItem value="hashicorp-vault" label="HashiCorp Vault">

1. Locate the `secretstore` attribute in `values.yaml`.
2. Add HashiCorp Vault configuration. For more information, see [HashiCorp Vault](https://docs.dapr.io/reference/components-reference/supported-secret-stores/hashicorp-vault/)

 ```yaml
 secretstore:
 enabled: true
 spec:
 type: secretstores.hashicorp.vault
 version: v1
 metadata:
 - name: vaultAddr
 value: "[vault_address]" # Optional. Default: "https://127.0.0.1:8200"
 - name: caCert # Optional. This or caPath or caPem
 value: "[ca_cert]"
 - name: caPath # Optional. This or CaCert or caPem
 value: "[path_to_ca_cert_file]"
 - name: caPem # Optional. This or CaCert or CaPath
 value: "[encoded_ca_cert_pem]"
 - name: skipVerify # Optional. Default: false
 value: "[skip_tls_verification]"
 - name: tlsServerName # Optional.
 value: "[tls_config_server_name]"
 - name: vaultTokenMountPath # Required if vaultToken not provided. Path to token file.
 value: "[path_to_file_containing_token]"
 - name: vaultToken # Required if vaultTokenMountPath not provided. Token value.
 value: "[vault_token]"
 - name: vaultKVPrefix # Optional. Default: "dapr"
 value: "[vault_prefix]"
 - name: vaultKVUsePrefix # Optional. default: "true"
 value: "[true/false]"
 - name: enginePath # Optional. default: "secret"
 value: "secret"
 - name: vaultValueType # Optional. default: "map"
 value: "map"
 ```

</TabItem>
<TabItem value="kubernetes-secrets" label="Kubernetes Secrets">

1. Locate the `secretstore` attribute in `values.yaml`.
2. Add Kubernetes native secret storage. For more information, see [Kubernetes secrets](https://docs.dapr.io/reference/components-reference/supported-secret-stores/kubernetes-secret-store/)

 ```yaml
 secretstore:
 enabled: true
 spec:
 type: secretstores.kubernetes
 version: v1
 metadata:
 - name: defaultNamespace
 value: "default" # Optional: Default namespace to retrieve secrets from
 - name: kubeconfigPath
 value: "/path/to/kubeconfig" # Optional: Path to kubeconfig file
 ```
 When Dapr is deployed to a Kubernetes cluster, a secret store with the name `kubernetes` is automatically provisioned. You can use this native Kubernetes secret store with no need to create, deploy or maintain a component configuration file.

</TabItem>
<TabItem value="environment-variable-based" label="Environment Variables">

1. Locate the `secretstore` attribute in `values.yaml`.
2. Add Local environment variables as the spec. For more information, see [Local Environment Variables](https://docs.dapr.io/reference/components-reference/supported-secret-stores/envvar-secret-store/)

 ```yaml
 secretstore:
 enabled: true
 spec:
 type: secretstores.local.env
 version: v1
 ```

</TabItem>
</Tabs>

### Image source

Choose how the cluster pulls the app image. Most installs use Atlan's Docker Hub directly; mirror to a private registry if your organization requires it.

<Tabs>
<TabItem value="docker-hub" label="Public Docker Hub" default>

The chart pulls the app image from Atlan's Docker Hub at runtime. The pod needs a Kubernetes secret containing your Docker Hub PAT to authenticate:

```bash
kubectl create secret docker-registry atlan-docker-secret \
 --docker-server=docker.io \
 --docker-username=YOUR_USERNAME \
 --docker-password=YOUR_PAT_TOKEN \
 -n <namespace>
```

- Replace `YOUR_USERNAME` with the Docker Hub username provided by Atlan.
- Replace `YOUR_PAT_TOKEN` with the Personal Access Token (PAT) provided by Atlan.
- Replace `<namespace>` with the namespace you need to install the chart into. The secret and the release must live in the same namespace, or the pod fails with `ImagePullBackOff`.

The downloaded `values.yaml` already references this secret under `imagePullSecrets`. If you use a different secret name, update that field in the file.

</TabItem>
<TabItem value="private-registry" label="Private image repo">

Mirror the Atlan image to your enterprise registry and update `values.yaml` to point at it.

1. Authenticate with Docker Hub using the PAT from Atlan, then pull the source image. The image and tag come from `image.repository` and `image.tag` in the downloaded `values.yaml`:

 ```bash
 docker login -u atlanhq
 # When prompted for password, enter the PAT provided by Atlan
 docker pull <image.repository>:<image.tag>
 ```

2. Push the image to your enterprise's registry. Note down the new repository name and image tag.

3. Update `image.repository` and `image.tag` in `values.yaml` with the new values.

4. If your private registry requires authentication, create an image-pull secret in the target namespace and set `imagePullSecrets` in `values.yaml` to its name.

</TabItem>
</Tabs>

<h2 id="deploy-app">Deploy app</h2>

Follow these steps to deploy the secure app:

* Install the helm chart. The chart directory now carries your edited `values.yaml`, so no `-f` flag is needed:

 ```bash
 helm install {{deploymentValues.helmChartName}}-release ./{{deploymentValues.helmChartName}} -n <namespace>
 ```

 - Replace `<namespace>` with your target Kubernetes namespace.
 - The helm chart name `{{deploymentValues.helmChartName}}` is automatically used from your selected app.

The deployment process typically takes a few minutes to complete depending on factors like Kubernetes cluster resource availability, private image repository download time etc.

<h2 id="verify-app">Verify app</h2>

Follow these steps to verify deployment:

### Verify deployment status on cluster

1. Check pod status:

 ```bash
 kubectl get pods -n <namespace>
 ```

 The output appears similar to:

 ```
 NAME READY STATUS RESTARTS AGE
 <helm-chart-name>-release-<helm-chart-name>-5dff95cd85-cvk5z 1/1 Running 0 2m
 ```
 
 Replace `<helm-chart-name>` with your app's helm chart name (shown in the prerequisites section earlier in this guide).

 The pod status shows `Running` with `1/1` ready containers.

2. Verify logs for the running pod
 
 ```bash
 kubectl logs -n <namespace> -l app.kubernetes.io/name={{deploymentValues.helmChartName}} --tail=50 -f
 ```
 **Example application logs**: Look for these key log messages that confirm successful deployment:

 * `Uvicorn running on http://0.0.0.0:8000` - Web server started
 * `Workflow engine initialized` - Workflow processing ready
 * `dapr initialized. Status: Running` - Dapr runtime active
 * `Starting worker with task queue: atlan-<package-name>-DEPLOYMENT_NAME` - Worker process started (replace `<package-name>` with your app's package name)
 * `GET /server/ready 200` - Health check endpoint responding

### Verify registration via Atlan UI

Once the App is successfully deployed, it communicates to the Atlan tenant and registers itself. Verify App registration is successful in Atlan:

1. In the same Atlan tenant, navigate to **Workflows** > **Agent**.
2. Look for an entry named `<app_name>-<deployment_name>`, where `<app_name>` matches your selected app (for example, "Oracle" or "Microsoft SQL Server") and `<deployment_name>` is the deployment name you entered when generating the config.
3. Confirm the agent status displays as **Active**.

Agent registration and status takes a couple of minutes to reflect in the Atlan UI.

<h2 id="next-steps">Next steps</h2>

* [Configure workflow execution](https://docs.atlan.com/product/connections/self-deployed-runtime/how-tos/configure-workflow-execution): Set up workflow execution with secret retrieval for your Self-deployed Runtime

---

## Install on Kubernetes - AlloyDB PostgreSQL

URL: https://docs.atlan.com/product/connections/self-deployed-runtime/how-tos/install-on-kubernetes
**Connector:** AlloyDB PostgreSQL (database)

> Install an App on Kubernetes using Helm charts, Docker images, and specific configuration

:::info **Did you know?** 
SDR requires additional enablement and licensing. Contact your Atlan representative for details.
:::

:::warning Use the guided install wizard instead
**New Self-Deployed Runtime setups are encouraged to use the [guided install wizard](https://docs.atlan.com/product/connections/self-deployed-runtime/how-tos/install-guided).** It assembles a complete guide tailored to your lifecycle mode, platform, and image procurement on a single page—and it's where new setup options (for example, HTTP proxy and custom CA trust) are documented going forward.

This page is kept for existing users who already reference it and may not include the latest steps.
:::

<h2 id="prerequisites">Prerequisites</h2>

Before you begin, make sure you have:

* `kubectl` installed and configured with administrative access to your target Kubernetes cluster
* Helm version 3.0 or later installed on your deployment machine
* A [Docker Hub Personal Access Token (PAT)](https://start.1password.com/open/i?a=WAVUZSKJO5GMNMVBYWAWECXIUE&v=ouvp3xf5334cxoamyiipzjlewy&i=p76avgzmkkcbftldcuvr5jcof4&h=atlanhq.1password.com) from Atlan
* App-specific helm chart name: `{{deploymentValues.helmChartName}}` 
* Object storage: AWS S3, Google Cloud Storage, or Azure Blob Storage with read/write permissions
* Secret store access: AWS Secret Manager, Azure Key Vault, GCP Secret Manager, HashiCorp Vault, or Kubernetes Secrets with read permissions

:::warning For security reasons, the Docker Hub PAT Token is regenerated on a periodic basis. 
In case the token is embedded in automation scripts or CI/CD pipelines, those jobs may fail. 
Contact your Atlan representative for the latest token.
:::

<h2 id="download-required-files">Download required files</h2>

<h3 id="download-helm-chart">Download Helm chart</h3>

Download the Helm chart for the app:

```bash
helm pull oci://registry-1.docker.io/atlanhq/{{deploymentValues.helmChartName}} --untar
```

This unpacks the chart's `Chart.yaml`, `templates/`, and a default `values.yaml` into `./{{deploymentValues.helmChartName}}/`. You'll replace this default `values.yaml` with your Marketplace copy in the next step.

<h3 id="download-values-yaml">Download values.yaml</h3>

Atlan generates the helm `values.yaml` for your runtime directly from the Marketplace UI, including the OAuth client credentials your runtime uses to authenticate to your tenant.

1. Sign in to your Atlan tenant as an administrator, open **Connector** > **Marketplace**, select the app you want to deploy, and click **Download config for Self-Deployed Runtime** in the right-hand sidebar.

2. In the dialog, keep **New deployment** selected (this mints the OAuth client and full config for a fresh runtime), choose **Kubernetes (Helm)** as the deployment target, and enter a **Deployment name**: a short identifier (lowercase letters, digits, and dashes) that identifies this runtime; the agent in **Workflows > Agent** is named `<app_name>-<deployment_name>`.

3. Click **Generate**. Atlan mints a dedicated OAuth client and produces a `values.yaml` file with:
 - `global.atlanBaseUrl`, `global.clientId`, and `global.clientSecret` already filled in.
 - `image.repository`, `image.tag`, and `name` pinned to the active version for your tenant.
 - `objectstore` and `secretstore` placeholders for you to configure below.

<h3 id="replace-chart-values">Replace chart values.yaml</h3>

Replace the default `values.yaml` inside the unpacked chart with the `values.yaml` you downloaded from the Marketplace.

From this point on, all edits to `values.yaml` must be made inside `./{{deploymentValues.helmChartName}}/`.

<h2 id="modify-values-yaml">Modify values.yaml</h2>

### Object storage

Self-Deployed Runtime needs a store for reading or writing files. Configure the object storage that matches your environment:

:::tip Don't see your preferred object store?
If your preferred object store isn't listed here, [reach out to Atlan support](https://docs.atlan.com/support/submit-request). Support for additional object stores may be available.
:::

<Tabs>
<TabItem value="aws-s3" label="AWS S3" default>

**Required permissions:**

Apply object-level actions to `arn:aws:s3:::BUCKET/*` and the list action to `arn:aws:s3:::BUCKET` in separate IAM statement entries.

| IAM action | Operations covered |
|---|---|
| `s3:GetObject` | GetObject (full and byte-range), HeadObject |
| `s3:PutObject` | PutObject, CreateMultipartUpload, UploadPart, CompleteMultipartUpload |
| `s3:AbortMultipartUpload` | Abort in-flight multipart upload on error (required for streaming write error paths) |
| `s3:DeleteObject` | DeleteObject and DeleteObjects (bulk batch—same IAM action) |
| `s3:ListBucket` | ListObjectsV2—bucket-level permission, not object-level |

```json
{
 "Version": "2012-10-17",
 "Statement": [
 {
 "Effect": "Allow",
 "Action": [
 "s3:GetObject",
 "s3:PutObject",
 "s3:AbortMultipartUpload",
 "s3:DeleteObject"
 ],
 "Resource": "arn:aws:s3:::YOUR-BUCKET/*"
 },
 {
 "Effect": "Allow",
 "Action": "s3:ListBucket",
 "Resource": "arn:aws:s3:::YOUR-BUCKET"
 }
 ]
}
```

**AssumeRole**: when using `assumeRoleArn`, the caller identity additionally needs `sts:AssumeRole` on the target role ARN. The role itself holds the bucket policy described earlier.

**Configure:**

 1. Locate the `objectstore` attribute in `values.yaml`.
 2. Add AWS S3 configuration. For more information, see [AWS S3 Binding Spec](https://docs.dapr.io/reference/components-reference/supported-bindings/s3/).

 ```yaml
 objectstore:
 enabled: true
 spec:
 type: bindings.aws.s3
 version: v1
 metadata:
 - name: accessKey #optional, leave this empty for iam authentication
 value: ""
 - name: secretKey #optional, leave this empty for iam authentication
 value: ""
 - name: bucket #required, name of the bucket where application can write
 value: "<bucket-name>"
 - name: region #required, region of the bucket where application can write
 value: "<bucket-region>"
 - name: forcePathStyle
 value: "true"
 ```

</TabItem>
<TabItem value="gcp-storage" label="Google Cloud Storage">

**Required permissions:**

| IAM permission | Operations covered |
|---|---|
| `storage.objects.get` | GetObject (full and byte-range), object metadata / HeadObject equivalent |
| `storage.objects.create` | PutObject, resumable / streaming write |
| `storage.objects.delete` | DeleteObject (GCS has no native bulk-delete API—`delete_prefix` issues parallel single-object deletes) |
| `storage.objects.list` | ListObjects |

No `storage.buckets.*` permissions are needed. The smallest predefined role that covers all four is **`roles/storage.objectAdmin`** scoped to the bucket. Alternatively, create a custom role with exactly these four permissions.

**Configure:**

 1. Locate the `objectstore` attribute in `values.yaml`.
 2. Add Google Cloud Storage configuration. For more information, see [GCP Storage Bucket binding spec](https://docs.dapr.io/reference/components-reference/supported-bindings/gcpbucket/)

 ```yaml
 objectstore:
 enabled: true
 spec:
 type: bindings.gcp.bucket
 version: v1
 metadata:
 - name: bucket
 value: "your-gcs-bucket-name"
 - name: type
 value: "service_account"
 - name: project_id
 value: "your-gcp-project-id"
 ```

</TabItem>
<TabItem value="azure-blob" label="Azure Blob Storage">

**Required permissions:**

**RBAC**—assign at container or storage-account scope:

| RBAC action | Operations covered |
|---|---|
| `Microsoft.Storage/storageAccounts/blobServices/containers/blobs/read` | GetBlob, GetBlobProperties (HEAD), ListBlobs, byte-range GET |
| `Microsoft.Storage/storageAccounts/blobServices/containers/blobs/write` | PutBlob, PutBlock + PutBlockList (streaming / block write) |
| `Microsoft.Storage/storageAccounts/blobServices/containers/blobs/delete` | DeleteBlob, BlobBatch delete (bulk—up to 256 keys per request) |

The smallest predefined role covering all three is **`Storage Blob Data Contributor`**. `Storage Blob Data Owner` is a superset and is only needed if you additionally require POSIX ACL management on ADLS Gen2.

**SAS token**—minimum permissions at container scope: `r` (read) + `w` (write) + `d` (delete) + `l` (list), that is a container-scoped SAS with **`rwdl`**.

**ADLS Gen2 with POSIX ACLs**: if the storage account has hierarchical namespace enabled and you use ACL-based access control instead of RBAC, the principal needs Execute (`X`) on every parent directory and Read / Write / Delete on the objects in scope. RBAC (`Storage Blob Data Contributor`) is simpler and is recommended unless you have a specific ACL requirement.

**Configure:**

 1. Locate the `objectstore` attribute in `values.yaml`.
 2. Add Azure Blob Storage configuration. For more information, see [Azure Blob Storage binding spec](https://docs.dapr.io/reference/components-reference/supported-bindings/blobstorage/)

 ```yaml
 objectstore:
 enabled: true
 spec:
 type: bindings.azure.blobstorage
 version: v1
 metadata:
 - name: accountName
 value: "your-storage-account-name"
 - name: accountKey
 value: "your-storage-account-key"
 - name: containerName
 value: "your-container-name"
 ```

</TabItem>
</Tabs>

### Secret storage

Self-Deployed Runtime fetches secrets from a secret store to connect to the source systems. The secret store references are used to configure the workflow. Configure the secret store that aligns with your security infrastructure:

:::info Did you know?
Dapr supports additional secret stores which aren't mentioned here. For more information, see [Dapr secret store documentation](https://docs.dapr.io/reference/components-reference/supported-secret-stores/) for other configurations.
:::

:::warning Secret content format and naming
When storing credentials, follow the [secret naming and format requirements](https://docs.atlan.com/product/connections/self-deployed-runtime/how-tos/configure-workflow-execution#secret-content-format).
:::

<Tabs>
<TabItem value="aws-secret-manager" label="AWS Secret Manager" default>
 
 1. Locate the `secretstore` attribute in `values.yaml`.
 2. Add AWS Secret Manager configuration. For more information, see [AWS Secrets Manager](https://docs.dapr.io/reference/components-reference/supported-secret-stores/aws-secret-manager/)

 ```yaml
 secretstore:
 enabled: true
 spec:
 type: secretstores.aws.secretmanager
 version: v1
 metadata:
 - name: region # required, region in which secret is hosted
 value: <secret-region>
 # Needed if IAM authentication is not used
 - name: accessKey
 value: ""
 - name: secretKey
 value: ""
 ```

If you are using IAM role / IRSA authentication, leave `accessKey` and `secretKey` empty.

If you are using an IAM user instead, set:
- `accessKey` to the IAM user's access key ID
- `secretKey` to the IAM user's secret access key

That IAM user must have permission to read the target secret from AWS Secrets Manager:

```json
{
 "Version": "2012-10-17",
 "Statement": [
 {
 "Effect": "Allow",
 "Action": [
 "secretsmanager:GetSecretValue",
 "secretsmanager:DescribeSecret"
 ],
 "Resource": "arn:aws:secretsmanager:<region>:<account-id>:secret:<secret-name>*"
 }
 ]
}
```

:::note
Include the trailing `*` in the secret ARN. AWS appends a random suffix to secret names in the ARN, so omitting it can cause access failures.
:::

</TabItem>
<TabItem value="azure-key-vault" label="Azure Key Vault">

 1. Locate the `secretstore` attribute in `values.yaml`.
 2. Add Azure Key Vault configuration. For more information, see [Azure Key Vault secret store](https://docs.dapr.io/reference/components-reference/supported-secret-stores/azure-keyvault/)

 ```yaml
 secretstore:
 enabled: true
 spec:
 type: secretstores.azure.keyvault
 version: v1
 metadata:
 - name: vaultName
 value: "<your-keyvault-name>"
 - name: azureTenantId
 value: "<your-tenant-id>"
 - name: azureClientId
 value: "<your-client-id>"
 - name: azureClientSecret
 value: "<your-client-secret>"
 - name: azureEnvironment
 value: "AZUREPUBLICCLOUD" # Optional: AZUREPUBLICCLOUD, AZURECHINACLOUD, AZUREUSGOVERNMENTCLOUD, AZUREGERMANCLOUD
 ```
 Azure Key Vault supports multiple authentication methods:
 - **Client Secret**: Use `azureClientSecret` with tenant ID and client ID
 - **Certificate**: Use `azureCertificateFile` instead of client secret
 - **Managed Identity**: Omit authentication fields and use Azure managed identity

 For detailed authentication setup, see the [Authenticating to Azure](https://docs.dapr.io/developing-applications/integrations/azure/azure-authentication/authenticating-azure/) documentation.

</TabItem>
<TabItem value="gcp-secret-manager" label="GCP Secret Manager">

1. Locate the `secretstore` attribute in `values.yaml`.
2. Add Google Cloud Secret Manager configuration. For more information, see [GCP Secret Manager](https://docs.dapr.io/reference/components-reference/supported-secret-stores/gcp-secret-manager/)

 The GCP service account used in this configuration must have the `Secret Manager Secret Accessor` role (`roles/secretmanager.secretAccessor`) on the project where your secrets are stored. The metadata values below come from the service account's JSON key file.

 ```yaml
 secretstore:
 enabled: true
 spec:
 type: secretstores.gcp.secretmanager
 version: v1
 metadata:
 - name: type
 value: "service_account"
 - name: project_id
 value: "<project-id>"
 - name: private_key_id
 value: "<private-key-id>"
 - name: private_key
 value: "<private-key>"
 - name: client_email
 value: "<client-email>"
 - name: client_id
 value: "<client-id>"
 - name: auth_uri
 value: "https://accounts.google.com/o/oauth2/auth"
 - name: token_uri
 value: "https://oauth2.googleapis.com/token"
 - name: auth_provider_x509_cert_url
 value: "https://www.googleapis.com/oauth2/v1/certs"
 - name: client_x509_cert_url
 value: "https://www.googleapis.com/robot/v1/metadata/x509/<client-email>"
 ```

</TabItem>
<TabItem value="hashicorp-vault" label="HashiCorp Vault">

1. Locate the `secretstore` attribute in `values.yaml`.
2. Add HashiCorp Vault configuration. For more information, see [HashiCorp Vault](https://docs.dapr.io/reference/components-reference/supported-secret-stores/hashicorp-vault/)

 ```yaml
 secretstore:
 enabled: true
 spec:
 type: secretstores.hashicorp.vault
 version: v1
 metadata:
 - name: vaultAddr
 value: "[vault_address]" # Optional. Default: "https://127.0.0.1:8200"
 - name: caCert # Optional. This or caPath or caPem
 value: "[ca_cert]"
 - name: caPath # Optional. This or CaCert or caPem
 value: "[path_to_ca_cert_file]"
 - name: caPem # Optional. This or CaCert or CaPath
 value: "[encoded_ca_cert_pem]"
 - name: skipVerify # Optional. Default: false
 value: "[skip_tls_verification]"
 - name: tlsServerName # Optional.
 value: "[tls_config_server_name]"
 - name: vaultTokenMountPath # Required if vaultToken not provided. Path to token file.
 value: "[path_to_file_containing_token]"
 - name: vaultToken # Required if vaultTokenMountPath not provided. Token value.
 value: "[vault_token]"
 - name: vaultKVPrefix # Optional. Default: "dapr"
 value: "[vault_prefix]"
 - name: vaultKVUsePrefix # Optional. default: "true"
 value: "[true/false]"
 - name: enginePath # Optional. default: "secret"
 value: "secret"
 - name: vaultValueType # Optional. default: "map"
 value: "map"
 ```

</TabItem>
<TabItem value="kubernetes-secrets" label="Kubernetes Secrets">

1. Locate the `secretstore` attribute in `values.yaml`.
2. Add Kubernetes native secret storage. For more information, see [Kubernetes secrets](https://docs.dapr.io/reference/components-reference/supported-secret-stores/kubernetes-secret-store/)

 ```yaml
 secretstore:
 enabled: true
 spec:
 type: secretstores.kubernetes
 version: v1
 metadata:
 - name: defaultNamespace
 value: "default" # Optional: Default namespace to retrieve secrets from
 - name: kubeconfigPath
 value: "/path/to/kubeconfig" # Optional: Path to kubeconfig file
 ```
 When Dapr is deployed to a Kubernetes cluster, a secret store with the name `kubernetes` is automatically provisioned. You can use this native Kubernetes secret store with no need to create, deploy or maintain a component configuration file.

</TabItem>
<TabItem value="environment-variable-based" label="Environment Variables">

1. Locate the `secretstore` attribute in `values.yaml`.
2. Add Local environment variables as the spec. For more information, see [Local Environment Variables](https://docs.dapr.io/reference/components-reference/supported-secret-stores/envvar-secret-store/)

 ```yaml
 secretstore:
 enabled: true
 spec:
 type: secretstores.local.env
 version: v1
 ```

</TabItem>
</Tabs>

### Image source

Choose how the cluster pulls the app image. Most installs use Atlan's Docker Hub directly; mirror to a private registry if your organization requires it.

<Tabs>
<TabItem value="docker-hub" label="Public Docker Hub" default>

The chart pulls the app image from Atlan's Docker Hub at runtime. The pod needs a Kubernetes secret containing your Docker Hub PAT to authenticate:

```bash
kubectl create secret docker-registry atlan-docker-secret \
 --docker-server=docker.io \
 --docker-username=YOUR_USERNAME \
 --docker-password=YOUR_PAT_TOKEN \
 -n <namespace>
```

- Replace `YOUR_USERNAME` with the Docker Hub username provided by Atlan.
- Replace `YOUR_PAT_TOKEN` with the Personal Access Token (PAT) provided by Atlan.
- Replace `<namespace>` with the namespace you need to install the chart into. The secret and the release must live in the same namespace, or the pod fails with `ImagePullBackOff`.

The downloaded `values.yaml` already references this secret under `imagePullSecrets`. If you use a different secret name, update that field in the file.

</TabItem>
<TabItem value="private-registry" label="Private image repo">

Mirror the Atlan image to your enterprise registry and update `values.yaml` to point at it.

1. Authenticate with Docker Hub using the PAT from Atlan, then pull the source image. The image and tag come from `image.repository` and `image.tag` in the downloaded `values.yaml`:

 ```bash
 docker login -u atlanhq
 # When prompted for password, enter the PAT provided by Atlan
 docker pull <image.repository>:<image.tag>
 ```

2. Push the image to your enterprise's registry. Note down the new repository name and image tag.

3. Update `image.repository` and `image.tag` in `values.yaml` with the new values.

4. If your private registry requires authentication, create an image-pull secret in the target namespace and set `imagePullSecrets` in `values.yaml` to its name.

</TabItem>
</Tabs>

<h2 id="deploy-app">Deploy app</h2>

Follow these steps to deploy the secure app:

* Install the helm chart. The chart directory now carries your edited `values.yaml`, so no `-f` flag is needed:

 ```bash
 helm install {{deploymentValues.helmChartName}}-release ./{{deploymentValues.helmChartName}} -n <namespace>
 ```

 - Replace `<namespace>` with your target Kubernetes namespace.
 - The helm chart name `{{deploymentValues.helmChartName}}` is automatically used from your selected app.

The deployment process typically takes a few minutes to complete depending on factors like Kubernetes cluster resource availability, private image repository download time etc.

<h2 id="verify-app">Verify app</h2>

Follow these steps to verify deployment:

### Verify deployment status on cluster

1. Check pod status:

 ```bash
 kubectl get pods -n <namespace>
 ```

 The output appears similar to:

 ```
 NAME READY STATUS RESTARTS AGE
 <helm-chart-name>-release-<helm-chart-name>-5dff95cd85-cvk5z 1/1 Running 0 2m
 ```
 
 Replace `<helm-chart-name>` with your app's helm chart name (shown in the prerequisites section earlier in this guide).

 The pod status shows `Running` with `1/1` ready containers.

2. Verify logs for the running pod
 
 ```bash
 kubectl logs -n <namespace> -l app.kubernetes.io/name={{deploymentValues.helmChartName}} --tail=50 -f
 ```
 **Example application logs**: Look for these key log messages that confirm successful deployment:

 * `Uvicorn running on http://0.0.0.0:8000` - Web server started
 * `Workflow engine initialized` - Workflow processing ready
 * `dapr initialized. Status: Running` - Dapr runtime active
 * `Starting worker with task queue: atlan-<package-name>-DEPLOYMENT_NAME` - Worker process started (replace `<package-name>` with your app's package name)
 * `GET /server/ready 200` - Health check endpoint responding

### Verify registration via Atlan UI

Once the App is successfully deployed, it communicates to the Atlan tenant and registers itself. Verify App registration is successful in Atlan:

1. In the same Atlan tenant, navigate to **Workflows** > **Agent**.
2. Look for an entry named `<app_name>-<deployment_name>`, where `<app_name>` matches your selected app (for example, "Oracle" or "Microsoft SQL Server") and `<deployment_name>` is the deployment name you entered when generating the config.
3. Confirm the agent status displays as **Active**.

Agent registration and status takes a couple of minutes to reflect in the Atlan UI.

<h2 id="next-steps">Next steps</h2>

* [Configure workflow execution](https://docs.atlan.com/product/connections/self-deployed-runtime/how-tos/configure-workflow-execution): Set up workflow execution with secret retrieval for your Self-deployed Runtime

---

## Install on Kubernetes - Amazon DocumentDB

URL: https://docs.atlan.com/product/connections/self-deployed-runtime/how-tos/install-on-kubernetes
**Connector:** Amazon DocumentDB (database)

> Install an App on Kubernetes using Helm charts, Docker images, and specific configuration

:::info **Did you know?** 
SDR requires additional enablement and licensing. Contact your Atlan representative for details.
:::

:::warning Use the guided install wizard instead
**New Self-Deployed Runtime setups are encouraged to use the [guided install wizard](https://docs.atlan.com/product/connections/self-deployed-runtime/how-tos/install-guided).** It assembles a complete guide tailored to your lifecycle mode, platform, and image procurement on a single page—and it's where new setup options (for example, HTTP proxy and custom CA trust) are documented going forward.

This page is kept for existing users who already reference it and may not include the latest steps.
:::

<h2 id="prerequisites">Prerequisites</h2>

Before you begin, make sure you have:

* `kubectl` installed and configured with administrative access to your target Kubernetes cluster
* Helm version 3.0 or later installed on your deployment machine
* A [Docker Hub Personal Access Token (PAT)](https://start.1password.com/open/i?a=WAVUZSKJO5GMNMVBYWAWECXIUE&v=ouvp3xf5334cxoamyiipzjlewy&i=p76avgzmkkcbftldcuvr5jcof4&h=atlanhq.1password.com) from Atlan
* App-specific helm chart name: `{{deploymentValues.helmChartName}}` 
* Object storage: AWS S3, Google Cloud Storage, or Azure Blob Storage with read/write permissions
* Secret store access: AWS Secret Manager, Azure Key Vault, GCP Secret Manager, HashiCorp Vault, or Kubernetes Secrets with read permissions

:::warning For security reasons, the Docker Hub PAT Token is regenerated on a periodic basis. 
In case the token is embedded in automation scripts or CI/CD pipelines, those jobs may fail. 
Contact your Atlan representative for the latest token.
:::

<h2 id="download-required-files">Download required files</h2>

<h3 id="download-helm-chart">Download Helm chart</h3>

Download the Helm chart for the app:

```bash
helm pull oci://registry-1.docker.io/atlanhq/{{deploymentValues.helmChartName}} --untar
```

This unpacks the chart's `Chart.yaml`, `templates/`, and a default `values.yaml` into `./{{deploymentValues.helmChartName}}/`. You'll replace this default `values.yaml` with your Marketplace copy in the next step.

<h3 id="download-values-yaml">Download values.yaml</h3>

Atlan generates the helm `values.yaml` for your runtime directly from the Marketplace UI, including the OAuth client credentials your runtime uses to authenticate to your tenant.

1. Sign in to your Atlan tenant as an administrator, open **Connector** > **Marketplace**, select the app you want to deploy, and click **Download config for Self-Deployed Runtime** in the right-hand sidebar.

2. In the dialog, keep **New deployment** selected (this mints the OAuth client and full config for a fresh runtime), choose **Kubernetes (Helm)** as the deployment target, and enter a **Deployment name**: a short identifier (lowercase letters, digits, and dashes) that identifies this runtime; the agent in **Workflows > Agent** is named `<app_name>-<deployment_name>`.

3. Click **Generate**. Atlan mints a dedicated OAuth client and produces a `values.yaml` file with:
 - `global.atlanBaseUrl`, `global.clientId`, and `global.clientSecret` already filled in.
 - `image.repository`, `image.tag`, and `name` pinned to the active version for your tenant.
 - `objectstore` and `secretstore` placeholders for you to configure below.

<h3 id="replace-chart-values">Replace chart values.yaml</h3>

Replace the default `values.yaml` inside the unpacked chart with the `values.yaml` you downloaded from the Marketplace.

From this point on, all edits to `values.yaml` must be made inside `./{{deploymentValues.helmChartName}}/`.

<h2 id="modify-values-yaml">Modify values.yaml</h2>

### Object storage

Self-Deployed Runtime needs a store for reading or writing files. Configure the object storage that matches your environment:

:::tip Don't see your preferred object store?
If your preferred object store isn't listed here, [reach out to Atlan support](https://docs.atlan.com/support/submit-request). Support for additional object stores may be available.
:::

<Tabs>
<TabItem value="aws-s3" label="AWS S3" default>

**Required permissions:**

Apply object-level actions to `arn:aws:s3:::BUCKET/*` and the list action to `arn:aws:s3:::BUCKET` in separate IAM statement entries.

| IAM action | Operations covered |
|---|---|
| `s3:GetObject` | GetObject (full and byte-range), HeadObject |
| `s3:PutObject` | PutObject, CreateMultipartUpload, UploadPart, CompleteMultipartUpload |
| `s3:AbortMultipartUpload` | Abort in-flight multipart upload on error (required for streaming write error paths) |
| `s3:DeleteObject` | DeleteObject and DeleteObjects (bulk batch—same IAM action) |
| `s3:ListBucket` | ListObjectsV2—bucket-level permission, not object-level |

```json
{
 "Version": "2012-10-17",
 "Statement": [
 {
 "Effect": "Allow",
 "Action": [
 "s3:GetObject",
 "s3:PutObject",
 "s3:AbortMultipartUpload",
 "s3:DeleteObject"
 ],
 "Resource": "arn:aws:s3:::YOUR-BUCKET/*"
 },
 {
 "Effect": "Allow",
 "Action": "s3:ListBucket",
 "Resource": "arn:aws:s3:::YOUR-BUCKET"
 }
 ]
}
```

**AssumeRole**: when using `assumeRoleArn`, the caller identity additionally needs `sts:AssumeRole` on the target role ARN. The role itself holds the bucket policy described earlier.

**Configure:**

 1. Locate the `objectstore` attribute in `values.yaml`.
 2. Add AWS S3 configuration. For more information, see [AWS S3 Binding Spec](https://docs.dapr.io/reference/components-reference/supported-bindings/s3/).

 ```yaml
 objectstore:
 enabled: true
 spec:
 type: bindings.aws.s3
 version: v1
 metadata:
 - name: accessKey #optional, leave this empty for iam authentication
 value: ""
 - name: secretKey #optional, leave this empty for iam authentication
 value: ""
 - name: bucket #required, name of the bucket where application can write
 value: "<bucket-name>"
 - name: region #required, region of the bucket where application can write
 value: "<bucket-region>"
 - name: forcePathStyle
 value: "true"
 ```

</TabItem>
<TabItem value="gcp-storage" label="Google Cloud Storage">

**Required permissions:**

| IAM permission | Operations covered |
|---|---|
| `storage.objects.get` | GetObject (full and byte-range), object metadata / HeadObject equivalent |
| `storage.objects.create` | PutObject, resumable / streaming write |
| `storage.objects.delete` | DeleteObject (GCS has no native bulk-delete API—`delete_prefix` issues parallel single-object deletes) |
| `storage.objects.list` | ListObjects |

No `storage.buckets.*` permissions are needed. The smallest predefined role that covers all four is **`roles/storage.objectAdmin`** scoped to the bucket. Alternatively, create a custom role with exactly these four permissions.

**Configure:**

 1. Locate the `objectstore` attribute in `values.yaml`.
 2. Add Google Cloud Storage configuration. For more information, see [GCP Storage Bucket binding spec](https://docs.dapr.io/reference/components-reference/supported-bindings/gcpbucket/)

 ```yaml
 objectstore:
 enabled: true
 spec:
 type: bindings.gcp.bucket
 version: v1
 metadata:
 - name: bucket
 value: "your-gcs-bucket-name"
 - name: type
 value: "service_account"
 - name: project_id
 value: "your-gcp-project-id"
 ```

</TabItem>
<TabItem value="azure-blob" label="Azure Blob Storage">

**Required permissions:**

**RBAC**—assign at container or storage-account scope:

| RBAC action | Operations covered |
|---|---|
| `Microsoft.Storage/storageAccounts/blobServices/containers/blobs/read` | GetBlob, GetBlobProperties (HEAD), ListBlobs, byte-range GET |
| `Microsoft.Storage/storageAccounts/blobServices/containers/blobs/write` | PutBlob, PutBlock + PutBlockList (streaming / block write) |
| `Microsoft.Storage/storageAccounts/blobServices/containers/blobs/delete` | DeleteBlob, BlobBatch delete (bulk—up to 256 keys per request) |

The smallest predefined role covering all three is **`Storage Blob Data Contributor`**. `Storage Blob Data Owner` is a superset and is only needed if you additionally require POSIX ACL management on ADLS Gen2.

**SAS token**—minimum permissions at container scope: `r` (read) + `w` (write) + `d` (delete) + `l` (list), that is a container-scoped SAS with **`rwdl`**.

**ADLS Gen2 with POSIX ACLs**: if the storage account has hierarchical namespace enabled and you use ACL-based access control instead of RBAC, the principal needs Execute (`X`) on every parent directory and Read / Write / Delete on the objects in scope. RBAC (`Storage Blob Data Contributor`) is simpler and is recommended unless you have a specific ACL requirement.

**Configure:**

 1. Locate the `objectstore` attribute in `values.yaml`.
 2. Add Azure Blob Storage configuration. For more information, see [Azure Blob Storage binding spec](https://docs.dapr.io/reference/components-reference/supported-bindings/blobstorage/)

 ```yaml
 objectstore:
 enabled: true
 spec:
 type: bindings.azure.blobstorage
 version: v1
 metadata:
 - name: accountName
 value: "your-storage-account-name"
 - name: accountKey
 value: "your-storage-account-key"
 - name: containerName
 value: "your-container-name"
 ```

</TabItem>
</Tabs>

### Secret storage

Self-Deployed Runtime fetches secrets from a secret store to connect to the source systems. The secret store references are used to configure the workflow. Configure the secret store that aligns with your security infrastructure:

:::info Did you know?
Dapr supports additional secret stores which aren't mentioned here. For more information, see [Dapr secret store documentation](https://docs.dapr.io/reference/components-reference/supported-secret-stores/) for other configurations.
:::

:::warning Secret content format and naming
When storing credentials, follow the [secret naming and format requirements](https://docs.atlan.com/product/connections/self-deployed-runtime/how-tos/configure-workflow-execution#secret-content-format).
:::

<Tabs>
<TabItem value="aws-secret-manager" label="AWS Secret Manager" default>
 
 1. Locate the `secretstore` attribute in `values.yaml`.
 2. Add AWS Secret Manager configuration. For more information, see [AWS Secrets Manager](https://docs.dapr.io/reference/components-reference/supported-secret-stores/aws-secret-manager/)

 ```yaml
 secretstore:
 enabled: true
 spec:
 type: secretstores.aws.secretmanager
 version: v1
 metadata:
 - name: region # required, region in which secret is hosted
 value: <secret-region>
 # Needed if IAM authentication is not used
 - name: accessKey
 value: ""
 - name: secretKey
 value: ""
 ```

If you are using IAM role / IRSA authentication, leave `accessKey` and `secretKey` empty.

If you are using an IAM user instead, set:
- `accessKey` to the IAM user's access key ID
- `secretKey` to the IAM user's secret access key

That IAM user must have permission to read the target secret from AWS Secrets Manager:

```json
{
 "Version": "2012-10-17",
 "Statement": [
 {
 "Effect": "Allow",
 "Action": [
 "secretsmanager:GetSecretValue",
 "secretsmanager:DescribeSecret"
 ],
 "Resource": "arn:aws:secretsmanager:<region>:<account-id>:secret:<secret-name>*"
 }
 ]
}
```

:::note
Include the trailing `*` in the secret ARN. AWS appends a random suffix to secret names in the ARN, so omitting it can cause access failures.
:::

</TabItem>
<TabItem value="azure-key-vault" label="Azure Key Vault">

 1. Locate the `secretstore` attribute in `values.yaml`.
 2. Add Azure Key Vault configuration. For more information, see [Azure Key Vault secret store](https://docs.dapr.io/reference/components-reference/supported-secret-stores/azure-keyvault/)

 ```yaml
 secretstore:
 enabled: true
 spec:
 type: secretstores.azure.keyvault
 version: v1
 metadata:
 - name: vaultName
 value: "<your-keyvault-name>"
 - name: azureTenantId
 value: "<your-tenant-id>"
 - name: azureClientId
 value: "<your-client-id>"
 - name: azureClientSecret
 value: "<your-client-secret>"
 - name: azureEnvironment
 value: "AZUREPUBLICCLOUD" # Optional: AZUREPUBLICCLOUD, AZURECHINACLOUD, AZUREUSGOVERNMENTCLOUD, AZUREGERMANCLOUD
 ```
 Azure Key Vault supports multiple authentication methods:
 - **Client Secret**: Use `azureClientSecret` with tenant ID and client ID
 - **Certificate**: Use `azureCertificateFile` instead of client secret
 - **Managed Identity**: Omit authentication fields and use Azure managed identity

 For detailed authentication setup, see the [Authenticating to Azure](https://docs.dapr.io/developing-applications/integrations/azure/azure-authentication/authenticating-azure/) documentation.

</TabItem>
<TabItem value="gcp-secret-manager" label="GCP Secret Manager">

1. Locate the `secretstore` attribute in `values.yaml`.
2. Add Google Cloud Secret Manager configuration. For more information, see [GCP Secret Manager](https://docs.dapr.io/reference/components-reference/supported-secret-stores/gcp-secret-manager/)

 The GCP service account used in this configuration must have the `Secret Manager Secret Accessor` role (`roles/secretmanager.secretAccessor`) on the project where your secrets are stored. The metadata values below come from the service account's JSON key file.

 ```yaml
 secretstore:
 enabled: true
 spec:
 type: secretstores.gcp.secretmanager
 version: v1
 metadata:
 - name: type
 value: "service_account"
 - name: project_id
 value: "<project-id>"
 - name: private_key_id
 value: "<private-key-id>"
 - name: private_key
 value: "<private-key>"
 - name: client_email
 value: "<client-email>"
 - name: client_id
 value: "<client-id>"
 - name: auth_uri
 value: "https://accounts.google.com/o/oauth2/auth"
 - name: token_uri
 value: "https://oauth2.googleapis.com/token"
 - name: auth_provider_x509_cert_url
 value: "https://www.googleapis.com/oauth2/v1/certs"
 - name: client_x509_cert_url
 value: "https://www.googleapis.com/robot/v1/metadata/x509/<client-email>"
 ```

</TabItem>
<TabItem value="hashicorp-vault" label="HashiCorp Vault">

1. Locate the `secretstore` attribute in `values.yaml`.
2. Add HashiCorp Vault configuration. For more information, see [HashiCorp Vault](https://docs.dapr.io/reference/components-reference/supported-secret-stores/hashicorp-vault/)

 ```yaml
 secretstore:
 enabled: true
 spec:
 type: secretstores.hashicorp.vault
 version: v1
 metadata:
 - name: vaultAddr
 value: "[vault_address]" # Optional. Default: "https://127.0.0.1:8200"
 - name: caCert # Optional. This or caPath or caPem
 value: "[ca_cert]"
 - name: caPath # Optional. This or CaCert or caPem
 value: "[path_to_ca_cert_file]"
 - name: caPem # Optional. This or CaCert or CaPath
 value: "[encoded_ca_cert_pem]"
 - name: skipVerify # Optional. Default: false
 value: "[skip_tls_verification]"
 - name: tlsServerName # Optional.
 value: "[tls_config_server_name]"
 - name: vaultTokenMountPath # Required if vaultToken not provided. Path to token file.
 value: "[path_to_file_containing_token]"
 - name: vaultToken # Required if vaultTokenMountPath not provided. Token value.
 value: "[vault_token]"
 - name: vaultKVPrefix # Optional. Default: "dapr"
 value: "[vault_prefix]"
 - name: vaultKVUsePrefix # Optional. default: "true"
 value: "[true/false]"
 - name: enginePath # Optional. default: "secret"
 value: "secret"
 - name: vaultValueType # Optional. default: "map"
 value: "map"
 ```

</TabItem>
<TabItem value="kubernetes-secrets" label="Kubernetes Secrets">

1. Locate the `secretstore` attribute in `values.yaml`.
2. Add Kubernetes native secret storage. For more information, see [Kubernetes secrets](https://docs.dapr.io/reference/components-reference/supported-secret-stores/kubernetes-secret-store/)

 ```yaml
 secretstore:
 enabled: true
 spec:
 type: secretstores.kubernetes
 version: v1
 metadata:
 - name: defaultNamespace
 value: "default" # Optional: Default namespace to retrieve secrets from
 - name: kubeconfigPath
 value: "/path/to/kubeconfig" # Optional: Path to kubeconfig file
 ```
 When Dapr is deployed to a Kubernetes cluster, a secret store with the name `kubernetes` is automatically provisioned. You can use this native Kubernetes secret store with no need to create, deploy or maintain a component configuration file.

</TabItem>
<TabItem value="environment-variable-based" label="Environment Variables">

1. Locate the `secretstore` attribute in `values.yaml`.
2. Add Local environment variables as the spec. For more information, see [Local Environment Variables](https://docs.dapr.io/reference/components-reference/supported-secret-stores/envvar-secret-store/)

 ```yaml
 secretstore:
 enabled: true
 spec:
 type: secretstores.local.env
 version: v1
 ```

</TabItem>
</Tabs>

### Image source

Choose how the cluster pulls the app image. Most installs use Atlan's Docker Hub directly; mirror to a private registry if your organization requires it.

<Tabs>
<TabItem value="docker-hub" label="Public Docker Hub" default>

The chart pulls the app image from Atlan's Docker Hub at runtime. The pod needs a Kubernetes secret containing your Docker Hub PAT to authenticate:

```bash
kubectl create secret docker-registry atlan-docker-secret \
 --docker-server=docker.io \
 --docker-username=YOUR_USERNAME \
 --docker-password=YOUR_PAT_TOKEN \
 -n <namespace>
```

- Replace `YOUR_USERNAME` with the Docker Hub username provided by Atlan.
- Replace `YOUR_PAT_TOKEN` with the Personal Access Token (PAT) provided by Atlan.
- Replace `<namespace>` with the namespace you need to install the chart into. The secret and the release must live in the same namespace, or the pod fails with `ImagePullBackOff`.

The downloaded `values.yaml` already references this secret under `imagePullSecrets`. If you use a different secret name, update that field in the file.

</TabItem>
<TabItem value="private-registry" label="Private image repo">

Mirror the Atlan image to your enterprise registry and update `values.yaml` to point at it.

1. Authenticate with Docker Hub using the PAT from Atlan, then pull the source image. The image and tag come from `image.repository` and `image.tag` in the downloaded `values.yaml`:

 ```bash
 docker login -u atlanhq
 # When prompted for password, enter the PAT provided by Atlan
 docker pull <image.repository>:<image.tag>
 ```

2. Push the image to your enterprise's registry. Note down the new repository name and image tag.

3. Update `image.repository` and `image.tag` in `values.yaml` with the new values.

4. If your private registry requires authentication, create an image-pull secret in the target namespace and set `imagePullSecrets` in `values.yaml` to its name.

</TabItem>
</Tabs>

<h2 id="deploy-app">Deploy app</h2>

Follow these steps to deploy the secure app:

* Install the helm chart. The chart directory now carries your edited `values.yaml`, so no `-f` flag is needed:

 ```bash
 helm install {{deploymentValues.helmChartName}}-release ./{{deploymentValues.helmChartName}} -n <namespace>
 ```

 - Replace `<namespace>` with your target Kubernetes namespace.
 - The helm chart name `{{deploymentValues.helmChartName}}` is automatically used from your selected app.

The deployment process typically takes a few minutes to complete depending on factors like Kubernetes cluster resource availability, private image repository download time etc.

<h2 id="verify-app">Verify app</h2>

Follow these steps to verify deployment:

### Verify deployment status on cluster

1. Check pod status:

 ```bash
 kubectl get pods -n <namespace>
 ```

 The output appears similar to:

 ```
 NAME READY STATUS RESTARTS AGE
 <helm-chart-name>-release-<helm-chart-name>-5dff95cd85-cvk5z 1/1 Running 0 2m
 ```
 
 Replace `<helm-chart-name>` with your app's helm chart name (shown in the prerequisites section earlier in this guide).

 The pod status shows `Running` with `1/1` ready containers.

2. Verify logs for the running pod
 
 ```bash
 kubectl logs -n <namespace> -l app.kubernetes.io/name={{deploymentValues.helmChartName}} --tail=50 -f
 ```
 **Example application logs**: Look for these key log messages that confirm successful deployment:

 * `Uvicorn running on http://0.0.0.0:8000` - Web server started
 * `Workflow engine initialized` - Workflow processing ready
 * `dapr initialized. Status: Running` - Dapr runtime active
 * `Starting worker with task queue: atlan-<package-name>-DEPLOYMENT_NAME` - Worker process started (replace `<package-name>` with your app's package name)
 * `GET /server/ready 200` - Health check endpoint responding

### Verify registration via Atlan UI

Once the App is successfully deployed, it communicates to the Atlan tenant and registers itself. Verify App registration is successful in Atlan:

1. In the same Atlan tenant, navigate to **Workflows** > **Agent**.
2. Look for an entry named `<app_name>-<deployment_name>`, where `<app_name>` matches your selected app (for example, "Oracle" or "Microsoft SQL Server") and `<deployment_name>` is the deployment name you entered when generating the config.
3. Confirm the agent status displays as **Active**.

Agent registration and status takes a couple of minutes to reflect in the Atlan UI.

<h2 id="next-steps">Next steps</h2>

* [Configure workflow execution](https://docs.atlan.com/product/connections/self-deployed-runtime/how-tos/configure-workflow-execution): Set up workflow execution with secret retrieval for your Self-deployed Runtime

---

## Install on Kubernetes - ClickHouse

URL: https://docs.atlan.com/product/connections/self-deployed-runtime/how-tos/install-on-kubernetes
**Connector:** ClickHouse (database)

> Install an App on Kubernetes using Helm charts, Docker images, and specific configuration

:::info **Did you know?** 
SDR requires additional enablement and licensing. Contact your Atlan representative for details.
:::

:::warning Use the guided install wizard instead
**New Self-Deployed Runtime setups are encouraged to use the [guided install wizard](https://docs.atlan.com/product/connections/self-deployed-runtime/how-tos/install-guided).** It assembles a complete guide tailored to your lifecycle mode, platform, and image procurement on a single page—and it's where new setup options (for example, HTTP proxy and custom CA trust) are documented going forward.

This page is kept for existing users who already reference it and may not include the latest steps.
:::

<h2 id="prerequisites">Prerequisites</h2>

Before you begin, make sure you have:

* `kubectl` installed and configured with administrative access to your target Kubernetes cluster
* Helm version 3.0 or later installed on your deployment machine
* A [Docker Hub Personal Access Token (PAT)](https://start.1password.com/open/i?a=WAVUZSKJO5GMNMVBYWAWECXIUE&v=ouvp3xf5334cxoamyiipzjlewy&i=p76avgzmkkcbftldcuvr5jcof4&h=atlanhq.1password.com) from Atlan
* App-specific helm chart name: `{{deploymentValues.helmChartName}}` 
* Object storage: AWS S3, Google Cloud Storage, or Azure Blob Storage with read/write permissions
* Secret store access: AWS Secret Manager, Azure Key Vault, GCP Secret Manager, HashiCorp Vault, or Kubernetes Secrets with read permissions

:::warning For security reasons, the Docker Hub PAT Token is regenerated on a periodic basis. 
In case the token is embedded in automation scripts or CI/CD pipelines, those jobs may fail. 
Contact your Atlan representative for the latest token.
:::

<h2 id="download-required-files">Download required files</h2>

<h3 id="download-helm-chart">Download Helm chart</h3>

Download the Helm chart for the app:

```bash
helm pull oci://registry-1.docker.io/atlanhq/{{deploymentValues.helmChartName}} --untar
```

This unpacks the chart's `Chart.yaml`, `templates/`, and a default `values.yaml` into `./{{deploymentValues.helmChartName}}/`. You'll replace this default `values.yaml` with your Marketplace copy in the next step.

<h3 id="download-values-yaml">Download values.yaml</h3>

Atlan generates the helm `values.yaml` for your runtime directly from the Marketplace UI, including the OAuth client credentials your runtime uses to authenticate to your tenant.

1. Sign in to your Atlan tenant as an administrator, open **Connector** > **Marketplace**, select the app you want to deploy, and click **Download config for Self-Deployed Runtime** in the right-hand sidebar.

2. In the dialog, keep **New deployment** selected (this mints the OAuth client and full config for a fresh runtime), choose **Kubernetes (Helm)** as the deployment target, and enter a **Deployment name**: a short identifier (lowercase letters, digits, and dashes) that identifies this runtime; the agent in **Workflows > Agent** is named `<app_name>-<deployment_name>`.

3. Click **Generate**. Atlan mints a dedicated OAuth client and produces a `values.yaml` file with:
 - `global.atlanBaseUrl`, `global.clientId`, and `global.clientSecret` already filled in.
 - `image.repository`, `image.tag`, and `name` pinned to the active version for your tenant.
 - `objectstore` and `secretstore` placeholders for you to configure below.

<h3 id="replace-chart-values">Replace chart values.yaml</h3>

Replace the default `values.yaml` inside the unpacked chart with the `values.yaml` you downloaded from the Marketplace.

From this point on, all edits to `values.yaml` must be made inside `./{{deploymentValues.helmChartName}}/`.

<h2 id="modify-values-yaml">Modify values.yaml</h2>

### Object storage

Self-Deployed Runtime needs a store for reading or writing files. Configure the object storage that matches your environment:

:::tip Don't see your preferred object store?
If your preferred object store isn't listed here, [reach out to Atlan support](https://docs.atlan.com/support/submit-request). Support for additional object stores may be available.
:::

<Tabs>
<TabItem value="aws-s3" label="AWS S3" default>

**Required permissions:**

Apply object-level actions to `arn:aws:s3:::BUCKET/*` and the list action to `arn:aws:s3:::BUCKET` in separate IAM statement entries.

| IAM action | Operations covered |
|---|---|
| `s3:GetObject` | GetObject (full and byte-range), HeadObject |
| `s3:PutObject` | PutObject, CreateMultipartUpload, UploadPart, CompleteMultipartUpload |
| `s3:AbortMultipartUpload` | Abort in-flight multipart upload on error (required for streaming write error paths) |
| `s3:DeleteObject` | DeleteObject and DeleteObjects (bulk batch—same IAM action) |
| `s3:ListBucket` | ListObjectsV2—bucket-level permission, not object-level |

```json
{
 "Version": "2012-10-17",
 "Statement": [
 {
 "Effect": "Allow",
 "Action": [
 "s3:GetObject",
 "s3:PutObject",
 "s3:AbortMultipartUpload",
 "s3:DeleteObject"
 ],
 "Resource": "arn:aws:s3:::YOUR-BUCKET/*"
 },
 {
 "Effect": "Allow",
 "Action": "s3:ListBucket",
 "Resource": "arn:aws:s3:::YOUR-BUCKET"
 }
 ]
}
```

**AssumeRole**: when using `assumeRoleArn`, the caller identity additionally needs `sts:AssumeRole` on the target role ARN. The role itself holds the bucket policy described earlier.

**Configure:**

 1. Locate the `objectstore` attribute in `values.yaml`.
 2. Add AWS S3 configuration. For more information, see [AWS S3 Binding Spec](https://docs.dapr.io/reference/components-reference/supported-bindings/s3/).

 ```yaml
 objectstore:
 enabled: true
 spec:
 type: bindings.aws.s3
 version: v1
 metadata:
 - name: accessKey #optional, leave this empty for iam authentication
 value: ""
 - name: secretKey #optional, leave this empty for iam authentication
 value: ""
 - name: bucket #required, name of the bucket where application can write
 value: "<bucket-name>"
 - name: region #required, region of the bucket where application can write
 value: "<bucket-region>"
 - name: forcePathStyle
 value: "true"
 ```

</TabItem>
<TabItem value="gcp-storage" label="Google Cloud Storage">

**Required permissions:**

| IAM permission | Operations covered |
|---|---|
| `storage.objects.get` | GetObject (full and byte-range), object metadata / HeadObject equivalent |
| `storage.objects.create` | PutObject, resumable / streaming write |
| `storage.objects.delete` | DeleteObject (GCS has no native bulk-delete API—`delete_prefix` issues parallel single-object deletes) |
| `storage.objects.list` | ListObjects |

No `storage.buckets.*` permissions are needed. The smallest predefined role that covers all four is **`roles/storage.objectAdmin`** scoped to the bucket. Alternatively, create a custom role with exactly these four permissions.

**Configure:**

 1. Locate the `objectstore` attribute in `values.yaml`.
 2. Add Google Cloud Storage configuration. For more information, see [GCP Storage Bucket binding spec](https://docs.dapr.io/reference/components-reference/supported-bindings/gcpbucket/)

 ```yaml
 objectstore:
 enabled: true
 spec:
 type: bindings.gcp.bucket
 version: v1
 metadata:
 - name: bucket
 value: "your-gcs-bucket-name"
 - name: type
 value: "service_account"
 - name: project_id
 value: "your-gcp-project-id"
 ```

</TabItem>
<TabItem value="azure-blob" label="Azure Blob Storage">

**Required permissions:**

**RBAC**—assign at container or storage-account scope:

| RBAC action | Operations covered |
|---|---|
| `Microsoft.Storage/storageAccounts/blobServices/containers/blobs/read` | GetBlob, GetBlobProperties (HEAD), ListBlobs, byte-range GET |
| `Microsoft.Storage/storageAccounts/blobServices/containers/blobs/write` | PutBlob, PutBlock + PutBlockList (streaming / block write) |
| `Microsoft.Storage/storageAccounts/blobServices/containers/blobs/delete` | DeleteBlob, BlobBatch delete (bulk—up to 256 keys per request) |

The smallest predefined role covering all three is **`Storage Blob Data Contributor`**. `Storage Blob Data Owner` is a superset and is only needed if you additionally require POSIX ACL management on ADLS Gen2.

**SAS token**—minimum permissions at container scope: `r` (read) + `w` (write) + `d` (delete) + `l` (list), that is a container-scoped SAS with **`rwdl`**.

**ADLS Gen2 with POSIX ACLs**: if the storage account has hierarchical namespace enabled and you use ACL-based access control instead of RBAC, the principal needs Execute (`X`) on every parent directory and Read / Write / Delete on the objects in scope. RBAC (`Storage Blob Data Contributor`) is simpler and is recommended unless you have a specific ACL requirement.

**Configure:**

 1. Locate the `objectstore` attribute in `values.yaml`.
 2. Add Azure Blob Storage configuration. For more information, see [Azure Blob Storage binding spec](https://docs.dapr.io/reference/components-reference/supported-bindings/blobstorage/)

 ```yaml
 objectstore:
 enabled: true
 spec:
 type: bindings.azure.blobstorage
 version: v1
 metadata:
 - name: accountName
 value: "your-storage-account-name"
 - name: accountKey
 value: "your-storage-account-key"
 - name: containerName
 value: "your-container-name"
 ```

</TabItem>
</Tabs>

### Secret storage

Self-Deployed Runtime fetches secrets from a secret store to connect to the source systems. The secret store references are used to configure the workflow. Configure the secret store that aligns with your security infrastructure:

:::info Did you know?
Dapr supports additional secret stores which aren't mentioned here. For more information, see [Dapr secret store documentation](https://docs.dapr.io/reference/components-reference/supported-secret-stores/) for other configurations.
:::

:::warning Secret content format and naming
When storing credentials, follow the [secret naming and format requirements](https://docs.atlan.com/product/connections/self-deployed-runtime/how-tos/configure-workflow-execution#secret-content-format).
:::

<Tabs>
<TabItem value="aws-secret-manager" label="AWS Secret Manager" default>
 
 1. Locate the `secretstore` attribute in `values.yaml`.
 2. Add AWS Secret Manager configuration. For more information, see [AWS Secrets Manager](https://docs.dapr.io/reference/components-reference/supported-secret-stores/aws-secret-manager/)

 ```yaml
 secretstore:
 enabled: true
 spec:
 type: secretstores.aws.secretmanager
 version: v1
 metadata:
 - name: region # required, region in which secret is hosted
 value: <secret-region>
 # Needed if IAM authentication is not used
 - name: accessKey
 value: ""
 - name: secretKey
 value: ""
 ```

If you are using IAM role / IRSA authentication, leave `accessKey` and `secretKey` empty.

If you are using an IAM user instead, set:
- `accessKey` to the IAM user's access key ID
- `secretKey` to the IAM user's secret access key

That IAM user must have permission to read the target secret from AWS Secrets Manager:

```json
{
 "Version": "2012-10-17",
 "Statement": [
 {
 "Effect": "Allow",
 "Action": [
 "secretsmanager:GetSecretValue",
 "secretsmanager:DescribeSecret"
 ],
 "Resource": "arn:aws:secretsmanager:<region>:<account-id>:secret:<secret-name>*"
 }
 ]
}
```

:::note
Include the trailing `*` in the secret ARN. AWS appends a random suffix to secret names in the ARN, so omitting it can cause access failures.
:::

</TabItem>
<TabItem value="azure-key-vault" label="Azure Key Vault">

 1. Locate the `secretstore` attribute in `values.yaml`.
 2. Add Azure Key Vault configuration. For more information, see [Azure Key Vault secret store](https://docs.dapr.io/reference/components-reference/supported-secret-stores/azure-keyvault/)

 ```yaml
 secretstore:
 enabled: true
 spec:
 type: secretstores.azure.keyvault
 version: v1
 metadata:
 - name: vaultName
 value: "<your-keyvault-name>"
 - name: azureTenantId
 value: "<your-tenant-id>"
 - name: azureClientId
 value: "<your-client-id>"
 - name: azureClientSecret
 value: "<your-client-secret>"
 - name: azureEnvironment
 value: "AZUREPUBLICCLOUD" # Optional: AZUREPUBLICCLOUD, AZURECHINACLOUD, AZUREUSGOVERNMENTCLOUD, AZUREGERMANCLOUD
 ```
 Azure Key Vault supports multiple authentication methods:
 - **Client Secret**: Use `azureClientSecret` with tenant ID and client ID
 - **Certificate**: Use `azureCertificateFile` instead of client secret
 - **Managed Identity**: Omit authentication fields and use Azure managed identity

 For detailed authentication setup, see the [Authenticating to Azure](https://docs.dapr.io/developing-applications/integrations/azure/azure-authentication/authenticating-azure/) documentation.

</TabItem>
<TabItem value="gcp-secret-manager" label="GCP Secret Manager">

1. Locate the `secretstore` attribute in `values.yaml`.
2. Add Google Cloud Secret Manager configuration. For more information, see [GCP Secret Manager](https://docs.dapr.io/reference/components-reference/supported-secret-stores/gcp-secret-manager/)

 The GCP service account used in this configuration must have the `Secret Manager Secret Accessor` role (`roles/secretmanager.secretAccessor`) on the project where your secrets are stored. The metadata values below come from the service account's JSON key file.

 ```yaml
 secretstore:
 enabled: true
 spec:
 type: secretstores.gcp.secretmanager
 version: v1
 metadata:
 - name: type
 value: "service_account"
 - name: project_id
 value: "<project-id>"
 - name: private_key_id
 value: "<private-key-id>"
 - name: private_key
 value: "<private-key>"
 - name: client_email
 value: "<client-email>"
 - name: client_id
 value: "<client-id>"
 - name: auth_uri
 value: "https://accounts.google.com/o/oauth2/auth"
 - name: token_uri
 value: "https://oauth2.googleapis.com/token"
 - name: auth_provider_x509_cert_url
 value: "https://www.googleapis.com/oauth2/v1/certs"
 - name: client_x509_cert_url
 value: "https://www.googleapis.com/robot/v1/metadata/x509/<client-email>"
 ```

</TabItem>
<TabItem value="hashicorp-vault" label="HashiCorp Vault">

1. Locate the `secretstore` attribute in `values.yaml`.
2. Add HashiCorp Vault configuration. For more information, see [HashiCorp Vault](https://docs.dapr.io/reference/components-reference/supported-secret-stores/hashicorp-vault/)

 ```yaml
 secretstore:
 enabled: true
 spec:
 type: secretstores.hashicorp.vault
 version: v1
 metadata:
 - name: vaultAddr
 value: "[vault_address]" # Optional. Default: "https://127.0.0.1:8200"
 - name: caCert # Optional. This or caPath or caPem
 value: "[ca_cert]"
 - name: caPath # Optional. This or CaCert or caPem
 value: "[path_to_ca_cert_file]"
 - name: caPem # Optional. This or CaCert or CaPath
 value: "[encoded_ca_cert_pem]"
 - name: skipVerify # Optional. Default: false
 value: "[skip_tls_verification]"
 - name: tlsServerName # Optional.
 value: "[tls_config_server_name]"
 - name: vaultTokenMountPath # Required if vaultToken not provided. Path to token file.
 value: "[path_to_file_containing_token]"
 - name: vaultToken # Required if vaultTokenMountPath not provided. Token value.
 value: "[vault_token]"
 - name: vaultKVPrefix # Optional. Default: "dapr"
 value: "[vault_prefix]"
 - name: vaultKVUsePrefix # Optional. default: "true"
 value: "[true/false]"
 - name: enginePath # Optional. default: "secret"
 value: "secret"
 - name: vaultValueType # Optional. default: "map"
 value: "map"
 ```

</TabItem>
<TabItem value="kubernetes-secrets" label="Kubernetes Secrets">

1. Locate the `secretstore` attribute in `values.yaml`.
2. Add Kubernetes native secret storage. For more information, see [Kubernetes secrets](https://docs.dapr.io/reference/components-reference/supported-secret-stores/kubernetes-secret-store/)

 ```yaml
 secretstore:
 enabled: true
 spec:
 type: secretstores.kubernetes
 version: v1
 metadata:
 - name: defaultNamespace
 value: "default" # Optional: Default namespace to retrieve secrets from
 - name: kubeconfigPath
 value: "/path/to/kubeconfig" # Optional: Path to kubeconfig file
 ```
 When Dapr is deployed to a Kubernetes cluster, a secret store with the name `kubernetes` is automatically provisioned. You can use this native Kubernetes secret store with no need to create, deploy or maintain a component configuration file.

</TabItem>
<TabItem value="environment-variable-based" label="Environment Variables">

1. Locate the `secretstore` attribute in `values.yaml`.
2. Add Local environment variables as the spec. For more information, see [Local Environment Variables](https://docs.dapr.io/reference/components-reference/supported-secret-stores/envvar-secret-store/)

 ```yaml
 secretstore:
 enabled: true
 spec:
 type: secretstores.local.env
 version: v1
 ```

</TabItem>
</Tabs>

### Image source

Choose how the cluster pulls the app image. Most installs use Atlan's Docker Hub directly; mirror to a private registry if your organization requires it.

<Tabs>
<TabItem value="docker-hub" label="Public Docker Hub" default>

The chart pulls the app image from Atlan's Docker Hub at runtime. The pod needs a Kubernetes secret containing your Docker Hub PAT to authenticate:

```bash
kubectl create secret docker-registry atlan-docker-secret \
 --docker-server=docker.io \
 --docker-username=YOUR_USERNAME \
 --docker-password=YOUR_PAT_TOKEN \
 -n <namespace>
```

- Replace `YOUR_USERNAME` with the Docker Hub username provided by Atlan.
- Replace `YOUR_PAT_TOKEN` with the Personal Access Token (PAT) provided by Atlan.
- Replace `<namespace>` with the namespace you need to install the chart into. The secret and the release must live in the same namespace, or the pod fails with `ImagePullBackOff`.

The downloaded `values.yaml` already references this secret under `imagePullSecrets`. If you use a different secret name, update that field in the file.

</TabItem>
<TabItem value="private-registry" label="Private image repo">

Mirror the Atlan image to your enterprise registry and update `values.yaml` to point at it.

1. Authenticate with Docker Hub using the PAT from Atlan, then pull the source image. The image and tag come from `image.repository` and `image.tag` in the downloaded `values.yaml`:

 ```bash
 docker login -u atlanhq
 # When prompted for password, enter the PAT provided by Atlan
 docker pull <image.repository>:<image.tag>
 ```

2. Push the image to your enterprise's registry. Note down the new repository name and image tag.

3. Update `image.repository` and `image.tag` in `values.yaml` with the new values.

4. If your private registry requires authentication, create an image-pull secret in the target namespace and set `imagePullSecrets` in `values.yaml` to its name.

</TabItem>
</Tabs>

<h2 id="deploy-app">Deploy app</h2>

Follow these steps to deploy the secure app:

* Install the helm chart. The chart directory now carries your edited `values.yaml`, so no `-f` flag is needed:

 ```bash
 helm install {{deploymentValues.helmChartName}}-release ./{{deploymentValues.helmChartName}} -n <namespace>
 ```

 - Replace `<namespace>` with your target Kubernetes namespace.
 - The helm chart name `{{deploymentValues.helmChartName}}` is automatically used from your selected app.

The deployment process typically takes a few minutes to complete depending on factors like Kubernetes cluster resource availability, private image repository download time etc.

<h2 id="verify-app">Verify app</h2>

Follow these steps to verify deployment:

### Verify deployment status on cluster

1. Check pod status:

 ```bash
 kubectl get pods -n <namespace>
 ```

 The output appears similar to:

 ```
 NAME READY STATUS RESTARTS AGE
 <helm-chart-name>-release-<helm-chart-name>-5dff95cd85-cvk5z 1/1 Running 0 2m
 ```
 
 Replace `<helm-chart-name>` with your app's helm chart name (shown in the prerequisites section earlier in this guide).

 The pod status shows `Running` with `1/1` ready containers.

2. Verify logs for the running pod
 
 ```bash
 kubectl logs -n <namespace> -l app.kubernetes.io/name={{deploymentValues.helmChartName}} --tail=50 -f
 ```
 **Example application logs**: Look for these key log messages that confirm successful deployment:

 * `Uvicorn running on http://0.0.0.0:8000` - Web server started
 * `Workflow engine initialized` - Workflow processing ready
 * `dapr initialized. Status: Running` - Dapr runtime active
 * `Starting worker with task queue: atlan-<package-name>-DEPLOYMENT_NAME` - Worker process started (replace `<package-name>` with your app's package name)
 * `GET /server/ready 200` - Health check endpoint responding

### Verify registration via Atlan UI

Once the App is successfully deployed, it communicates to the Atlan tenant and registers itself. Verify App registration is successful in Atlan:

1. In the same Atlan tenant, navigate to **Workflows** > **Agent**.
2. Look for an entry named `<app_name>-<deployment_name>`, where `<app_name>` matches your selected app (for example, "Oracle" or "Microsoft SQL Server") and `<deployment_name>` is the deployment name you entered when generating the config.
3. Confirm the agent status displays as **Active**.

Agent registration and status takes a couple of minutes to reflect in the Atlan UI.

<h2 id="next-steps">Next steps</h2>

* [Configure workflow execution](https://docs.atlan.com/product/connections/self-deployed-runtime/how-tos/configure-workflow-execution): Set up workflow execution with secret retrieval for your Self-deployed Runtime

---

## Install on Kubernetes - Cloud SQL PostgreSQL

URL: https://docs.atlan.com/product/connections/self-deployed-runtime/how-tos/install-on-kubernetes
**Connector:** Cloud SQL PostgreSQL (database)

> Install an App on Kubernetes using Helm charts, Docker images, and specific configuration

:::info **Did you know?** 
SDR requires additional enablement and licensing. Contact your Atlan representative for details.
:::

:::warning Use the guided install wizard instead
**New Self-Deployed Runtime setups are encouraged to use the [guided install wizard](https://docs.atlan.com/product/connections/self-deployed-runtime/how-tos/install-guided).** It assembles a complete guide tailored to your lifecycle mode, platform, and image procurement on a single page—and it's where new setup options (for example, HTTP proxy and custom CA trust) are documented going forward.

This page is kept for existing users who already reference it and may not include the latest steps.
:::

<h2 id="prerequisites">Prerequisites</h2>

Before you begin, make sure you have:

* `kubectl` installed and configured with administrative access to your target Kubernetes cluster
* Helm version 3.0 or later installed on your deployment machine
* A [Docker Hub Personal Access Token (PAT)](https://start.1password.com/open/i?a=WAVUZSKJO5GMNMVBYWAWECXIUE&v=ouvp3xf5334cxoamyiipzjlewy&i=p76avgzmkkcbftldcuvr5jcof4&h=atlanhq.1password.com) from Atlan
* App-specific helm chart name: `{{deploymentValues.helmChartName}}` 
* Object storage: AWS S3, Google Cloud Storage, or Azure Blob Storage with read/write permissions
* Secret store access: AWS Secret Manager, Azure Key Vault, GCP Secret Manager, HashiCorp Vault, or Kubernetes Secrets with read permissions

:::warning For security reasons, the Docker Hub PAT Token is regenerated on a periodic basis. 
In case the token is embedded in automation scripts or CI/CD pipelines, those jobs may fail. 
Contact your Atlan representative for the latest token.
:::

<h2 id="download-required-files">Download required files</h2>

<h3 id="download-helm-chart">Download Helm chart</h3>

Download the Helm chart for the app:

```bash
helm pull oci://registry-1.docker.io/atlanhq/{{deploymentValues.helmChartName}} --untar
```

This unpacks the chart's `Chart.yaml`, `templates/`, and a default `values.yaml` into `./{{deploymentValues.helmChartName}}/`. You'll replace this default `values.yaml` with your Marketplace copy in the next step.

<h3 id="download-values-yaml">Download values.yaml</h3>

Atlan generates the helm `values.yaml` for your runtime directly from the Marketplace UI, including the OAuth client credentials your runtime uses to authenticate to your tenant.

1. Sign in to your Atlan tenant as an administrator, open **Connector** > **Marketplace**, select the app you want to deploy, and click **Download config for Self-Deployed Runtime** in the right-hand sidebar.

2. In the dialog, keep **New deployment** selected (this mints the OAuth client and full config for a fresh runtime), choose **Kubernetes (Helm)** as the deployment target, and enter a **Deployment name**: a short identifier (lowercase letters, digits, and dashes) that identifies this runtime; the agent in **Workflows > Agent** is named `<app_name>-<deployment_name>`.

3. Click **Generate**. Atlan mints a dedicated OAuth client and produces a `values.yaml` file with:
 - `global.atlanBaseUrl`, `global.clientId`, and `global.clientSecret` already filled in.
 - `image.repository`, `image.tag`, and `name` pinned to the active version for your tenant.
 - `objectstore` and `secretstore` placeholders for you to configure below.

<h3 id="replace-chart-values">Replace chart values.yaml</h3>

Replace the default `values.yaml` inside the unpacked chart with the `values.yaml` you downloaded from the Marketplace.

From this point on, all edits to `values.yaml` must be made inside `./{{deploymentValues.helmChartName}}/`.

<h2 id="modify-values-yaml">Modify values.yaml</h2>

### Object storage

Self-Deployed Runtime needs a store for reading or writing files. Configure the object storage that matches your environment:

:::tip Don't see your preferred object store?
If your preferred object store isn't listed here, [reach out to Atlan support](https://docs.atlan.com/support/submit-request). Support for additional object stores may be available.
:::

<Tabs>
<TabItem value="aws-s3" label="AWS S3" default>

**Required permissions:**

Apply object-level actions to `arn:aws:s3:::BUCKET/*` and the list action to `arn:aws:s3:::BUCKET` in separate IAM statement entries.

| IAM action | Operations covered |
|---|---|
| `s3:GetObject` | GetObject (full and byte-range), HeadObject |
| `s3:PutObject` | PutObject, CreateMultipartUpload, UploadPart, CompleteMultipartUpload |
| `s3:AbortMultipartUpload` | Abort in-flight multipart upload on error (required for streaming write error paths) |
| `s3:DeleteObject` | DeleteObject and DeleteObjects (bulk batch—same IAM action) |
| `s3:ListBucket` | ListObjectsV2—bucket-level permission, not object-level |

```json
{
 "Version": "2012-10-17",
 "Statement": [
 {
 "Effect": "Allow",
 "Action": [
 "s3:GetObject",
 "s3:PutObject",
 "s3:AbortMultipartUpload",
 "s3:DeleteObject"
 ],
 "Resource": "arn:aws:s3:::YOUR-BUCKET/*"
 },
 {
 "Effect": "Allow",
 "Action": "s3:ListBucket",
 "Resource": "arn:aws:s3:::YOUR-BUCKET"
 }
 ]
}
```

**AssumeRole**: when using `assumeRoleArn`, the caller identity additionally needs `sts:AssumeRole` on the target role ARN. The role itself holds the bucket policy described earlier.

**Configure:**

 1. Locate the `objectstore` attribute in `values.yaml`.
 2. Add AWS S3 configuration. For more information, see [AWS S3 Binding Spec](https://docs.dapr.io/reference/components-reference/supported-bindings/s3/).

 ```yaml
 objectstore:
 enabled: true
 spec:
 type: bindings.aws.s3
 version: v1
 metadata:
 - name: accessKey #optional, leave this empty for iam authentication
 value: ""
 - name: secretKey #optional, leave this empty for iam authentication
 value: ""
 - name: bucket #required, name of the bucket where application can write
 value: "<bucket-name>"
 - name: region #required, region of the bucket where application can write
 value: "<bucket-region>"
 - name: forcePathStyle
 value: "true"
 ```

</TabItem>
<TabItem value="gcp-storage" label="Google Cloud Storage">

**Required permissions:**

| IAM permission | Operations covered |
|---|---|
| `storage.objects.get` | GetObject (full and byte-range), object metadata / HeadObject equivalent |
| `storage.objects.create` | PutObject, resumable / streaming write |
| `storage.objects.delete` | DeleteObject (GCS has no native bulk-delete API—`delete_prefix` issues parallel single-object deletes) |
| `storage.objects.list` | ListObjects |

No `storage.buckets.*` permissions are needed. The smallest predefined role that covers all four is **`roles/storage.objectAdmin`** scoped to the bucket. Alternatively, create a custom role with exactly these four permissions.

**Configure:**

 1. Locate the `objectstore` attribute in `values.yaml`.
 2. Add Google Cloud Storage configuration. For more information, see [GCP Storage Bucket binding spec](https://docs.dapr.io/reference/components-reference/supported-bindings/gcpbucket/)

 ```yaml
 objectstore:
 enabled: true
 spec:
 type: bindings.gcp.bucket
 version: v1
 metadata:
 - name: bucket
 value: "your-gcs-bucket-name"
 - name: type
 value: "service_account"
 - name: project_id
 value: "your-gcp-project-id"
 ```

</TabItem>
<TabItem value="azure-blob" label="Azure Blob Storage">

**Required permissions:**

**RBAC**—assign at container or storage-account scope:

| RBAC action | Operations covered |
|---|---|
| `Microsoft.Storage/storageAccounts/blobServices/containers/blobs/read` | GetBlob, GetBlobProperties (HEAD), ListBlobs, byte-range GET |
| `Microsoft.Storage/storageAccounts/blobServices/containers/blobs/write` | PutBlob, PutBlock + PutBlockList (streaming / block write) |
| `Microsoft.Storage/storageAccounts/blobServices/containers/blobs/delete` | DeleteBlob, BlobBatch delete (bulk—up to 256 keys per request) |

The smallest predefined role covering all three is **`Storage Blob Data Contributor`**. `Storage Blob Data Owner` is a superset and is only needed if you additionally require POSIX ACL management on ADLS Gen2.

**SAS token**—minimum permissions at container scope: `r` (read) + `w` (write) + `d` (delete) + `l` (list), that is a container-scoped SAS with **`rwdl`**.

**ADLS Gen2 with POSIX ACLs**: if the storage account has hierarchical namespace enabled and you use ACL-based access control instead of RBAC, the principal needs Execute (`X`) on every parent directory and Read / Write / Delete on the objects in scope. RBAC (`Storage Blob Data Contributor`) is simpler and is recommended unless you have a specific ACL requirement.

**Configure:**

 1. Locate the `objectstore` attribute in `values.yaml`.
 2. Add Azure Blob Storage configuration. For more information, see [Azure Blob Storage binding spec](https://docs.dapr.io/reference/components-reference/supported-bindings/blobstorage/)

 ```yaml
 objectstore:
 enabled: true
 spec:
 type: bindings.azure.blobstorage
 version: v1
 metadata:
 - name: accountName
 value: "your-storage-account-name"
 - name: accountKey
 value: "your-storage-account-key"
 - name: containerName
 value: "your-container-name"
 ```

</TabItem>
</Tabs>

### Secret storage

Self-Deployed Runtime fetches secrets from a secret store to connect to the source systems. The secret store references are used to configure the workflow. Configure the secret store that aligns with your security infrastructure:

:::info Did you know?
Dapr supports additional secret stores which aren't mentioned here. For more information, see [Dapr secret store documentation](https://docs.dapr.io/reference/components-reference/supported-secret-stores/) for other configurations.
:::

:::warning Secret content format and naming
When storing credentials, follow the [secret naming and format requirements](https://docs.atlan.com/product/connections/self-deployed-runtime/how-tos/configure-workflow-execution#secret-content-format).
:::

<Tabs>
<TabItem value="aws-secret-manager" label="AWS Secret Manager" default>
 
 1. Locate the `secretstore` attribute in `values.yaml`.
 2. Add AWS Secret Manager configuration. For more information, see [AWS Secrets Manager](https://docs.dapr.io/reference/components-reference/supported-secret-stores/aws-secret-manager/)

 ```yaml
 secretstore:
 enabled: true
 spec:
 type: secretstores.aws.secretmanager
 version: v1
 metadata:
 - name: region # required, region in which secret is hosted
 value: <secret-region>
 # Needed if IAM authentication is not used
 - name: accessKey
 value: ""
 - name: secretKey
 value: ""
 ```

If you are using IAM role / IRSA authentication, leave `accessKey` and `secretKey` empty.

If you are using an IAM user instead, set:
- `accessKey` to the IAM user's access key ID
- `secretKey` to the IAM user's secret access key

That IAM user must have permission to read the target secret from AWS Secrets Manager:

```json
{
 "Version": "2012-10-17",
 "Statement": [
 {
 "Effect": "Allow",
 "Action": [
 "secretsmanager:GetSecretValue",
 "secretsmanager:DescribeSecret"
 ],
 "Resource": "arn:aws:secretsmanager:<region>:<account-id>:secret:<secret-name>*"
 }
 ]
}
```

:::note
Include the trailing `*` in the secret ARN. AWS appends a random suffix to secret names in the ARN, so omitting it can cause access failures.
:::

</TabItem>
<TabItem value="azure-key-vault" label="Azure Key Vault">

 1. Locate the `secretstore` attribute in `values.yaml`.
 2. Add Azure Key Vault configuration. For more information, see [Azure Key Vault secret store](https://docs.dapr.io/reference/components-reference/supported-secret-stores/azure-keyvault/)

 ```yaml
 secretstore:
 enabled: true
 spec:
 type: secretstores.azure.keyvault
 version: v1
 metadata:
 - name: vaultName
 value: "<your-keyvault-name>"
 - name: azureTenantId
 value: "<your-tenant-id>"
 - name: azureClientId
 value: "<your-client-id>"
 - name: azureClientSecret
 value: "<your-client-secret>"
 - name: azureEnvironment
 value: "AZUREPUBLICCLOUD" # Optional: AZUREPUBLICCLOUD, AZURECHINACLOUD, AZUREUSGOVERNMENTCLOUD, AZUREGERMANCLOUD
 ```
 Azure Key Vault supports multiple authentication methods:
 - **Client Secret**: Use `azureClientSecret` with tenant ID and client ID
 - **Certificate**: Use `azureCertificateFile` instead of client secret
 - **Managed Identity**: Omit authentication fields and use Azure managed identity

 For detailed authentication setup, see the [Authenticating to Azure](https://docs.dapr.io/developing-applications/integrations/azure/azure-authentication/authenticating-azure/) documentation.

</TabItem>
<TabItem value="gcp-secret-manager" label="GCP Secret Manager">

1. Locate the `secretstore` attribute in `values.yaml`.
2. Add Google Cloud Secret Manager configuration. For more information, see [GCP Secret Manager](https://docs.dapr.io/reference/components-reference/supported-secret-stores/gcp-secret-manager/)

 The GCP service account used in this configuration must have the `Secret Manager Secret Accessor` role (`roles/secretmanager.secretAccessor`) on the project where your secrets are stored. The metadata values below come from the service account's JSON key file.

 ```yaml
 secretstore:
 enabled: true
 spec:
 type: secretstores.gcp.secretmanager
 version: v1
 metadata:
 - name: type
 value: "service_account"
 - name: project_id
 value: "<project-id>"
 - name: private_key_id
 value: "<private-key-id>"
 - name: private_key
 value: "<private-key>"
 - name: client_email
 value: "<client-email>"
 - name: client_id
 value: "<client-id>"
 - name: auth_uri
 value: "https://accounts.google.com/o/oauth2/auth"
 - name: token_uri
 value: "https://oauth2.googleapis.com/token"
 - name: auth_provider_x509_cert_url
 value: "https://www.googleapis.com/oauth2/v1/certs"
 - name: client_x509_cert_url
 value: "https://www.googleapis.com/robot/v1/metadata/x509/<client-email>"
 ```

</TabItem>
<TabItem value="hashicorp-vault" label="HashiCorp Vault">

1. Locate the `secretstore` attribute in `values.yaml`.
2. Add HashiCorp Vault configuration. For more information, see [HashiCorp Vault](https://docs.dapr.io/reference/components-reference/supported-secret-stores/hashicorp-vault/)

 ```yaml
 secretstore:
 enabled: true
 spec:
 type: secretstores.hashicorp.vault
 version: v1
 metadata:
 - name: vaultAddr
 value: "[vault_address]" # Optional. Default: "https://127.0.0.1:8200"
 - name: caCert # Optional. This or caPath or caPem
 value: "[ca_cert]"
 - name: caPath # Optional. This or CaCert or caPem
 value: "[path_to_ca_cert_file]"
 - name: caPem # Optional. This or CaCert or CaPath
 value: "[encoded_ca_cert_pem]"
 - name: skipVerify # Optional. Default: false
 value: "[skip_tls_verification]"
 - name: tlsServerName # Optional.
 value: "[tls_config_server_name]"
 - name: vaultTokenMountPath # Required if vaultToken not provided. Path to token file.
 value: "[path_to_file_containing_token]"
 - name: vaultToken # Required if vaultTokenMountPath not provided. Token value.
 value: "[vault_token]"
 - name: vaultKVPrefix # Optional. Default: "dapr"
 value: "[vault_prefix]"
 - name: vaultKVUsePrefix # Optional. default: "true"
 value: "[true/false]"
 - name: enginePath # Optional. default: "secret"
 value: "secret"
 - name: vaultValueType # Optional. default: "map"
 value: "map"
 ```

</TabItem>
<TabItem value="kubernetes-secrets" label="Kubernetes Secrets">

1. Locate the `secretstore` attribute in `values.yaml`.
2. Add Kubernetes native secret storage. For more information, see [Kubernetes secrets](https://docs.dapr.io/reference/components-reference/supported-secret-stores/kubernetes-secret-store/)

 ```yaml
 secretstore:
 enabled: true
 spec:
 type: secretstores.kubernetes
 version: v1
 metadata:
 - name: defaultNamespace
 value: "default" # Optional: Default namespace to retrieve secrets from
 - name: kubeconfigPath
 value: "/path/to/kubeconfig" # Optional: Path to kubeconfig file
 ```
 When Dapr is deployed to a Kubernetes cluster, a secret store with the name `kubernetes` is automatically provisioned. You can use this native Kubernetes secret store with no need to create, deploy or maintain a component configuration file.

</TabItem>
<TabItem value="environment-variable-based" label="Environment Variables">

1. Locate the `secretstore` attribute in `values.yaml`.
2. Add Local environment variables as the spec. For more information, see [Local Environment Variables](https://docs.dapr.io/reference/components-reference/supported-secret-stores/envvar-secret-store/)

 ```yaml
 secretstore:
 enabled: true
 spec:
 type: secretstores.local.env
 version: v1
 ```

</TabItem>
</Tabs>

### Image source

Choose how the cluster pulls the app image. Most installs use Atlan's Docker Hub directly; mirror to a private registry if your organization requires it.

<Tabs>
<TabItem value="docker-hub" label="Public Docker Hub" default>

The chart pulls the app image from Atlan's Docker Hub at runtime. The pod needs a Kubernetes secret containing your Docker Hub PAT to authenticate:

```bash
kubectl create secret docker-registry atlan-docker-secret \
 --docker-server=docker.io \
 --docker-username=YOUR_USERNAME \
 --docker-password=YOUR_PAT_TOKEN \
 -n <namespace>
```

- Replace `YOUR_USERNAME` with the Docker Hub username provided by Atlan.
- Replace `YOUR_PAT_TOKEN` with the Personal Access Token (PAT) provided by Atlan.
- Replace `<namespace>` with the namespace you need to install the chart into. The secret and the release must live in the same namespace, or the pod fails with `ImagePullBackOff`.

The downloaded `values.yaml` already references this secret under `imagePullSecrets`. If you use a different secret name, update that field in the file.

</TabItem>
<TabItem value="private-registry" label="Private image repo">

Mirror the Atlan image to your enterprise registry and update `values.yaml` to point at it.

1. Authenticate with Docker Hub using the PAT from Atlan, then pull the source image. The image and tag come from `image.repository` and `image.tag` in the downloaded `values.yaml`:

 ```bash
 docker login -u atlanhq
 # When prompted for password, enter the PAT provided by Atlan
 docker pull <image.repository>:<image.tag>
 ```

2. Push the image to your enterprise's registry. Note down the new repository name and image tag.

3. Update `image.repository` and `image.tag` in `values.yaml` with the new values.

4. If your private registry requires authentication, create an image-pull secret in the target namespace and set `imagePullSecrets` in `values.yaml` to its name.

</TabItem>
</Tabs>

<h2 id="deploy-app">Deploy app</h2>

Follow these steps to deploy the secure app:

* Install the helm chart. The chart directory now carries your edited `values.yaml`, so no `-f` flag is needed:

 ```bash
 helm install {{deploymentValues.helmChartName}}-release ./{{deploymentValues.helmChartName}} -n <namespace>
 ```

 - Replace `<namespace>` with your target Kubernetes namespace.
 - The helm chart name `{{deploymentValues.helmChartName}}` is automatically used from your selected app.

The deployment process typically takes a few minutes to complete depending on factors like Kubernetes cluster resource availability, private image repository download time etc.

<h2 id="verify-app">Verify app</h2>

Follow these steps to verify deployment:

### Verify deployment status on cluster

1. Check pod status:

 ```bash
 kubectl get pods -n <namespace>
 ```

 The output appears similar to:

 ```
 NAME READY STATUS RESTARTS AGE
 <helm-chart-name>-release-<helm-chart-name>-5dff95cd85-cvk5z 1/1 Running 0 2m
 ```
 
 Replace `<helm-chart-name>` with your app's helm chart name (shown in the prerequisites section earlier in this guide).

 The pod status shows `Running` with `1/1` ready containers.

2. Verify logs for the running pod
 
 ```bash
 kubectl logs -n <namespace> -l app.kubernetes.io/name={{deploymentValues.helmChartName}} --tail=50 -f
 ```
 **Example application logs**: Look for these key log messages that confirm successful deployment:

 * `Uvicorn running on http://0.0.0.0:8000` - Web server started
 * `Workflow engine initialized` - Workflow processing ready
 * `dapr initialized. Status: Running` - Dapr runtime active
 * `Starting worker with task queue: atlan-<package-name>-DEPLOYMENT_NAME` - Worker process started (replace `<package-name>` with your app's package name)
 * `GET /server/ready 200` - Health check endpoint responding

### Verify registration via Atlan UI

Once the App is successfully deployed, it communicates to the Atlan tenant and registers itself. Verify App registration is successful in Atlan:

1. In the same Atlan tenant, navigate to **Workflows** > **Agent**.
2. Look for an entry named `<app_name>-<deployment_name>`, where `<app_name>` matches your selected app (for example, "Oracle" or "Microsoft SQL Server") and `<deployment_name>` is the deployment name you entered when generating the config.
3. Confirm the agent status displays as **Active**.

Agent registration and status takes a couple of minutes to reflect in the Atlan UI.

<h2 id="next-steps">Next steps</h2>

* [Configure workflow execution](https://docs.atlan.com/product/connections/self-deployed-runtime/how-tos/configure-workflow-execution): Set up workflow execution with secret retrieval for your Self-deployed Runtime

---

## Install on Kubernetes - Hive

URL: https://docs.atlan.com/product/connections/self-deployed-runtime/how-tos/install-on-kubernetes
**Connector:** Hive (database)

> Install an App on Kubernetes using Helm charts, Docker images, and specific configuration

:::info **Did you know?** 
SDR requires additional enablement and licensing. Contact your Atlan representative for details.
:::

:::warning Use the guided install wizard instead
**New Self-Deployed Runtime setups are encouraged to use the [guided install wizard](https://docs.atlan.com/product/connections/self-deployed-runtime/how-tos/install-guided).** It assembles a complete guide tailored to your lifecycle mode, platform, and image procurement on a single page—and it's where new setup options (for example, HTTP proxy and custom CA trust) are documented going forward.

This page is kept for existing users who already reference it and may not include the latest steps.
:::

<h2 id="prerequisites">Prerequisites</h2>

Before you begin, make sure you have:

* `kubectl` installed and configured with administrative access to your target Kubernetes cluster
* Helm version 3.0 or later installed on your deployment machine
* A [Docker Hub Personal Access Token (PAT)](https://start.1password.com/open/i?a=WAVUZSKJO5GMNMVBYWAWECXIUE&v=ouvp3xf5334cxoamyiipzjlewy&i=p76avgzmkkcbftldcuvr5jcof4&h=atlanhq.1password.com) from Atlan
* App-specific helm chart name: `{{deploymentValues.helmChartName}}` 
* Object storage: AWS S3, Google Cloud Storage, or Azure Blob Storage with read/write permissions
* Secret store access: AWS Secret Manager, Azure Key Vault, GCP Secret Manager, HashiCorp Vault, or Kubernetes Secrets with read permissions

:::warning For security reasons, the Docker Hub PAT Token is regenerated on a periodic basis. 
In case the token is embedded in automation scripts or CI/CD pipelines, those jobs may fail. 
Contact your Atlan representative for the latest token.
:::

<h2 id="download-required-files">Download required files</h2>

<h3 id="download-helm-chart">Download Helm chart</h3>

Download the Helm chart for the app:

```bash
helm pull oci://registry-1.docker.io/atlanhq/{{deploymentValues.helmChartName}} --untar
```

This unpacks the chart's `Chart.yaml`, `templates/`, and a default `values.yaml` into `./{{deploymentValues.helmChartName}}/`. You'll replace this default `values.yaml` with your Marketplace copy in the next step.

<h3 id="download-values-yaml">Download values.yaml</h3>

Atlan generates the helm `values.yaml` for your runtime directly from the Marketplace UI, including the OAuth client credentials your runtime uses to authenticate to your tenant.

1. Sign in to your Atlan tenant as an administrator, open **Connector** > **Marketplace**, select the app you want to deploy, and click **Download config for Self-Deployed Runtime** in the right-hand sidebar.

2. In the dialog, keep **New deployment** selected (this mints the OAuth client and full config for a fresh runtime), choose **Kubernetes (Helm)** as the deployment target, and enter a **Deployment name**: a short identifier (lowercase letters, digits, and dashes) that identifies this runtime; the agent in **Workflows > Agent** is named `<app_name>-<deployment_name>`.

3. Click **Generate**. Atlan mints a dedicated OAuth client and produces a `values.yaml` file with:
 - `global.atlanBaseUrl`, `global.clientId`, and `global.clientSecret` already filled in.
 - `image.repository`, `image.tag`, and `name` pinned to the active version for your tenant.
 - `objectstore` and `secretstore` placeholders for you to configure below.

<h3 id="replace-chart-values">Replace chart values.yaml</h3>

Replace the default `values.yaml` inside the unpacked chart with the `values.yaml` you downloaded from the Marketplace.

From this point on, all edits to `values.yaml` must be made inside `./{{deploymentValues.helmChartName}}/`.

<h2 id="modify-values-yaml">Modify values.yaml</h2>

### Object storage

Self-Deployed Runtime needs a store for reading or writing files. Configure the object storage that matches your environment:

:::tip Don't see your preferred object store?
If your preferred object store isn't listed here, [reach out to Atlan support](https://docs.atlan.com/support/submit-request). Support for additional object stores may be available.
:::

<Tabs>
<TabItem value="aws-s3" label="AWS S3" default>

**Required permissions:**

Apply object-level actions to `arn:aws:s3:::BUCKET/*` and the list action to `arn:aws:s3:::BUCKET` in separate IAM statement entries.

| IAM action | Operations covered |
|---|---|
| `s3:GetObject` | GetObject (full and byte-range), HeadObject |
| `s3:PutObject` | PutObject, CreateMultipartUpload, UploadPart, CompleteMultipartUpload |
| `s3:AbortMultipartUpload` | Abort in-flight multipart upload on error (required for streaming write error paths) |
| `s3:DeleteObject` | DeleteObject and DeleteObjects (bulk batch—same IAM action) |
| `s3:ListBucket` | ListObjectsV2—bucket-level permission, not object-level |

```json
{
 "Version": "2012-10-17",
 "Statement": [
 {
 "Effect": "Allow",
 "Action": [
 "s3:GetObject",
 "s3:PutObject",
 "s3:AbortMultipartUpload",
 "s3:DeleteObject"
 ],
 "Resource": "arn:aws:s3:::YOUR-BUCKET/*"
 },
 {
 "Effect": "Allow",
 "Action": "s3:ListBucket",
 "Resource": "arn:aws:s3:::YOUR-BUCKET"
 }
 ]
}
```

**AssumeRole**: when using `assumeRoleArn`, the caller identity additionally needs `sts:AssumeRole` on the target role ARN. The role itself holds the bucket policy described earlier.

**Configure:**

 1. Locate the `objectstore` attribute in `values.yaml`.
 2. Add AWS S3 configuration. For more information, see [AWS S3 Binding Spec](https://docs.dapr.io/reference/components-reference/supported-bindings/s3/).

 ```yaml
 objectstore:
 enabled: true
 spec:
 type: bindings.aws.s3
 version: v1
 metadata:
 - name: accessKey #optional, leave this empty for iam authentication
 value: ""
 - name: secretKey #optional, leave this empty for iam authentication
 value: ""
 - name: bucket #required, name of the bucket where application can write
 value: "<bucket-name>"
 - name: region #required, region of the bucket where application can write
 value: "<bucket-region>"
 - name: forcePathStyle
 value: "true"
 ```

</TabItem>
<TabItem value="gcp-storage" label="Google Cloud Storage">

**Required permissions:**

| IAM permission | Operations covered |
|---|---|
| `storage.objects.get` | GetObject (full and byte-range), object metadata / HeadObject equivalent |
| `storage.objects.create` | PutObject, resumable / streaming write |
| `storage.objects.delete` | DeleteObject (GCS has no native bulk-delete API—`delete_prefix` issues parallel single-object deletes) |
| `storage.objects.list` | ListObjects |

No `storage.buckets.*` permissions are needed. The smallest predefined role that covers all four is **`roles/storage.objectAdmin`** scoped to the bucket. Alternatively, create a custom role with exactly these four permissions.

**Configure:**

 1. Locate the `objectstore` attribute in `values.yaml`.
 2. Add Google Cloud Storage configuration. For more information, see [GCP Storage Bucket binding spec](https://docs.dapr.io/reference/components-reference/supported-bindings/gcpbucket/)

 ```yaml
 objectstore:
 enabled: true
 spec:
 type: bindings.gcp.bucket
 version: v1
 metadata:
 - name: bucket
 value: "your-gcs-bucket-name"
 - name: type
 value: "service_account"
 - name: project_id
 value: "your-gcp-project-id"
 ```

</TabItem>
<TabItem value="azure-blob" label="Azure Blob Storage">

**Required permissions:**

**RBAC**—assign at container or storage-account scope:

| RBAC action | Operations covered |
|---|---|
| `Microsoft.Storage/storageAccounts/blobServices/containers/blobs/read` | GetBlob, GetBlobProperties (HEAD), ListBlobs, byte-range GET |
| `Microsoft.Storage/storageAccounts/blobServices/containers/blobs/write` | PutBlob, PutBlock + PutBlockList (streaming / block write) |
| `Microsoft.Storage/storageAccounts/blobServices/containers/blobs/delete` | DeleteBlob, BlobBatch delete (bulk—up to 256 keys per request) |

The smallest predefined role covering all three is **`Storage Blob Data Contributor`**. `Storage Blob Data Owner` is a superset and is only needed if you additionally require POSIX ACL management on ADLS Gen2.

**SAS token**—minimum permissions at container scope: `r` (read) + `w` (write) + `d` (delete) + `l` (list), that is a container-scoped SAS with **`rwdl`**.

**ADLS Gen2 with POSIX ACLs**: if the storage account has hierarchical namespace enabled and you use ACL-based access control instead of RBAC, the principal needs Execute (`X`) on every parent directory and Read / Write / Delete on the objects in scope. RBAC (`Storage Blob Data Contributor`) is simpler and is recommended unless you have a specific ACL requirement.

**Configure:**

 1. Locate the `objectstore` attribute in `values.yaml`.
 2. Add Azure Blob Storage configuration. For more information, see [Azure Blob Storage binding spec](https://docs.dapr.io/reference/components-reference/supported-bindings/blobstorage/)

 ```yaml
 objectstore:
 enabled: true
 spec:
 type: bindings.azure.blobstorage
 version: v1
 metadata:
 - name: accountName
 value: "your-storage-account-name"
 - name: accountKey
 value: "your-storage-account-key"
 - name: containerName
 value: "your-container-name"
 ```

</TabItem>
</Tabs>

### Secret storage

Self-Deployed Runtime fetches secrets from a secret store to connect to the source systems. The secret store references are used to configure the workflow. Configure the secret store that aligns with your security infrastructure:

:::info Did you know?
Dapr supports additional secret stores which aren't mentioned here. For more information, see [Dapr secret store documentation](https://docs.dapr.io/reference/components-reference/supported-secret-stores/) for other configurations.
:::

:::warning Secret content format and naming
When storing credentials, follow the [secret naming and format requirements](https://docs.atlan.com/product/connections/self-deployed-runtime/how-tos/configure-workflow-execution#secret-content-format).
:::

<Tabs>
<TabItem value="aws-secret-manager" label="AWS Secret Manager" default>
 
 1. Locate the `secretstore` attribute in `values.yaml`.
 2. Add AWS Secret Manager configuration. For more information, see [AWS Secrets Manager](https://docs.dapr.io/reference/components-reference/supported-secret-stores/aws-secret-manager/)

 ```yaml
 secretstore:
 enabled: true
 spec:
 type: secretstores.aws.secretmanager
 version: v1
 metadata:
 - name: region # required, region in which secret is hosted
 value: <secret-region>
 # Needed if IAM authentication is not used
 - name: accessKey
 value: ""
 - name: secretKey
 value: ""
 ```

If you are using IAM role / IRSA authentication, leave `accessKey` and `secretKey` empty.

If you are using an IAM user instead, set:
- `accessKey` to the IAM user's access key ID
- `secretKey` to the IAM user's secret access key

That IAM user must have permission to read the target secret from AWS Secrets Manager:

```json
{
 "Version": "2012-10-17",
 "Statement": [
 {
 "Effect": "Allow",
 "Action": [
 "secretsmanager:GetSecretValue",
 "secretsmanager:DescribeSecret"
 ],
 "Resource": "arn:aws:secretsmanager:<region>:<account-id>:secret:<secret-name>*"
 }
 ]
}
```

:::note
Include the trailing `*` in the secret ARN. AWS appends a random suffix to secret names in the ARN, so omitting it can cause access failures.
:::

</TabItem>
<TabItem value="azure-key-vault" label="Azure Key Vault">

 1. Locate the `secretstore` attribute in `values.yaml`.
 2. Add Azure Key Vault configuration. For more information, see [Azure Key Vault secret store](https://docs.dapr.io/reference/components-reference/supported-secret-stores/azure-keyvault/)

 ```yaml
 secretstore:
 enabled: true
 spec:
 type: secretstores.azure.keyvault
 version: v1
 metadata:
 - name: vaultName
 value: "<your-keyvault-name>"
 - name: azureTenantId
 value: "<your-tenant-id>"
 - name: azureClientId
 value: "<your-client-id>"
 - name: azureClientSecret
 value: "<your-client-secret>"
 - name: azureEnvironment
 value: "AZUREPUBLICCLOUD" # Optional: AZUREPUBLICCLOUD, AZURECHINACLOUD, AZUREUSGOVERNMENTCLOUD, AZUREGERMANCLOUD
 ```
 Azure Key Vault supports multiple authentication methods:
 - **Client Secret**: Use `azureClientSecret` with tenant ID and client ID
 - **Certificate**: Use `azureCertificateFile` instead of client secret
 - **Managed Identity**: Omit authentication fields and use Azure managed identity

 For detailed authentication setup, see the [Authenticating to Azure](https://docs.dapr.io/developing-applications/integrations/azure/azure-authentication/authenticating-azure/) documentation.

</TabItem>
<TabItem value="gcp-secret-manager" label="GCP Secret Manager">

1. Locate the `secretstore` attribute in `values.yaml`.
2. Add Google Cloud Secret Manager configuration. For more information, see [GCP Secret Manager](https://docs.dapr.io/reference/components-reference/supported-secret-stores/gcp-secret-manager/)

 The GCP service account used in this configuration must have the `Secret Manager Secret Accessor` role (`roles/secretmanager.secretAccessor`) on the project where your secrets are stored. The metadata values below come from the service account's JSON key file.

 ```yaml
 secretstore:
 enabled: true
 spec:
 type: secretstores.gcp.secretmanager
 version: v1
 metadata:
 - name: type
 value: "service_account"
 - name: project_id
 value: "<project-id>"
 - name: private_key_id
 value: "<private-key-id>"
 - name: private_key
 value: "<private-key>"
 - name: client_email
 value: "<client-email>"
 - name: client_id
 value: "<client-id>"
 - name: auth_uri
 value: "https://accounts.google.com/o/oauth2/auth"
 - name: token_uri
 value: "https://oauth2.googleapis.com/token"
 - name: auth_provider_x509_cert_url
 value: "https://www.googleapis.com/oauth2/v1/certs"
 - name: client_x509_cert_url
 value: "https://www.googleapis.com/robot/v1/metadata/x509/<client-email>"
 ```

</TabItem>
<TabItem value="hashicorp-vault" label="HashiCorp Vault">

1. Locate the `secretstore` attribute in `values.yaml`.
2. Add HashiCorp Vault configuration. For more information, see [HashiCorp Vault](https://docs.dapr.io/reference/components-reference/supported-secret-stores/hashicorp-vault/)

 ```yaml
 secretstore:
 enabled: true
 spec:
 type: secretstores.hashicorp.vault
 version: v1
 metadata:
 - name: vaultAddr
 value: "[vault_address]" # Optional. Default: "https://127.0.0.1:8200"
 - name: caCert # Optional. This or caPath or caPem
 value: "[ca_cert]"
 - name: caPath # Optional. This or CaCert or caPem
 value: "[path_to_ca_cert_file]"
 - name: caPem # Optional. This or CaCert or CaPath
 value: "[encoded_ca_cert_pem]"
 - name: skipVerify # Optional. Default: false
 value: "[skip_tls_verification]"
 - name: tlsServerName # Optional.
 value: "[tls_config_server_name]"
 - name: vaultTokenMountPath # Required if vaultToken not provided. Path to token file.
 value: "[path_to_file_containing_token]"
 - name: vaultToken # Required if vaultTokenMountPath not provided. Token value.
 value: "[vault_token]"
 - name: vaultKVPrefix # Optional. Default: "dapr"
 value: "[vault_prefix]"
 - name: vaultKVUsePrefix # Optional. default: "true"
 value: "[true/false]"
 - name: enginePath # Optional. default: "secret"
 value: "secret"
 - name: vaultValueType # Optional. default: "map"
 value: "map"
 ```

</TabItem>
<TabItem value="kubernetes-secrets" label="Kubernetes Secrets">

1. Locate the `secretstore` attribute in `values.yaml`.
2. Add Kubernetes native secret storage. For more information, see [Kubernetes secrets](https://docs.dapr.io/reference/components-reference/supported-secret-stores/kubernetes-secret-store/)

 ```yaml
 secretstore:
 enabled: true
 spec:
 type: secretstores.kubernetes
 version: v1
 metadata:
 - name: defaultNamespace
 value: "default" # Optional: Default namespace to retrieve secrets from
 - name: kubeconfigPath
 value: "/path/to/kubeconfig" # Optional: Path to kubeconfig file
 ```
 When Dapr is deployed to a Kubernetes cluster, a secret store with the name `kubernetes` is automatically provisioned. You can use this native Kubernetes secret store with no need to create, deploy or maintain a component configuration file.

</TabItem>
<TabItem value="environment-variable-based" label="Environment Variables">

1. Locate the `secretstore` attribute in `values.yaml`.
2. Add Local environment variables as the spec. For more information, see [Local Environment Variables](https://docs.dapr.io/reference/components-reference/supported-secret-stores/envvar-secret-store/)

 ```yaml
 secretstore:
 enabled: true
 spec:
 type: secretstores.local.env
 version: v1
 ```

</TabItem>
</Tabs>

### Image source

Choose how the cluster pulls the app image. Most installs use Atlan's Docker Hub directly; mirror to a private registry if your organization requires it.

<Tabs>
<TabItem value="docker-hub" label="Public Docker Hub" default>

The chart pulls the app image from Atlan's Docker Hub at runtime. The pod needs a Kubernetes secret containing your Docker Hub PAT to authenticate:

```bash
kubectl create secret docker-registry atlan-docker-secret \
 --docker-server=docker.io \
 --docker-username=YOUR_USERNAME \
 --docker-password=YOUR_PAT_TOKEN \
 -n <namespace>
```

- Replace `YOUR_USERNAME` with the Docker Hub username provided by Atlan.
- Replace `YOUR_PAT_TOKEN` with the Personal Access Token (PAT) provided by Atlan.
- Replace `<namespace>` with the namespace you need to install the chart into. The secret and the release must live in the same namespace, or the pod fails with `ImagePullBackOff`.

The downloaded `values.yaml` already references this secret under `imagePullSecrets`. If you use a different secret name, update that field in the file.

</TabItem>
<TabItem value="private-registry" label="Private image repo">

Mirror the Atlan image to your enterprise registry and update `values.yaml` to point at it.

1. Authenticate with Docker Hub using the PAT from Atlan, then pull the source image. The image and tag come from `image.repository` and `image.tag` in the downloaded `values.yaml`:

 ```bash
 docker login -u atlanhq
 # When prompted for password, enter the PAT provided by Atlan
 docker pull <image.repository>:<image.tag>
 ```

2. Push the image to your enterprise's registry. Note down the new repository name and image tag.

3. Update `image.repository` and `image.tag` in `values.yaml` with the new values.

4. If your private registry requires authentication, create an image-pull secret in the target namespace and set `imagePullSecrets` in `values.yaml` to its name.

</TabItem>
</Tabs>

<h2 id="deploy-app">Deploy app</h2>

Follow these steps to deploy the secure app:

* Install the helm chart. The chart directory now carries your edited `values.yaml`, so no `-f` flag is needed:

 ```bash
 helm install {{deploymentValues.helmChartName}}-release ./{{deploymentValues.helmChartName}} -n <namespace>
 ```

 - Replace `<namespace>` with your target Kubernetes namespace.
 - The helm chart name `{{deploymentValues.helmChartName}}` is automatically used from your selected app.

The deployment process typically takes a few minutes to complete depending on factors like Kubernetes cluster resource availability, private image repository download time etc.

<h2 id="verify-app">Verify app</h2>

Follow these steps to verify deployment:

### Verify deployment status on cluster

1. Check pod status:

 ```bash
 kubectl get pods -n <namespace>
 ```

 The output appears similar to:

 ```
 NAME READY STATUS RESTARTS AGE
 <helm-chart-name>-release-<helm-chart-name>-5dff95cd85-cvk5z 1/1 Running 0 2m
 ```
 
 Replace `<helm-chart-name>` with your app's helm chart name (shown in the prerequisites section earlier in this guide).

 The pod status shows `Running` with `1/1` ready containers.

2. Verify logs for the running pod
 
 ```bash
 kubectl logs -n <namespace> -l app.kubernetes.io/name={{deploymentValues.helmChartName}} --tail=50 -f
 ```
 **Example application logs**: Look for these key log messages that confirm successful deployment:

 * `Uvicorn running on http://0.0.0.0:8000` - Web server started
 * `Workflow engine initialized` - Workflow processing ready
 * `dapr initialized. Status: Running` - Dapr runtime active
 * `Starting worker with task queue: atlan-<package-name>-DEPLOYMENT_NAME` - Worker process started (replace `<package-name>` with your app's package name)
 * `GET /server/ready 200` - Health check endpoint responding

### Verify registration via Atlan UI

Once the App is successfully deployed, it communicates to the Atlan tenant and registers itself. Verify App registration is successful in Atlan:

1. In the same Atlan tenant, navigate to **Workflows** > **Agent**.
2. Look for an entry named `<app_name>-<deployment_name>`, where `<app_name>` matches your selected app (for example, "Oracle" or "Microsoft SQL Server") and `<deployment_name>` is the deployment name you entered when generating the config.
3. Confirm the agent status displays as **Active**.

Agent registration and status takes a couple of minutes to reflect in the Atlan UI.

<h2 id="next-steps">Next steps</h2>

* [Configure workflow execution](https://docs.atlan.com/product/connections/self-deployed-runtime/how-tos/configure-workflow-execution): Set up workflow execution with secret retrieval for your Self-deployed Runtime

---

## Install on Kubernetes - Microsoft SQL Server

URL: https://docs.atlan.com/product/connections/self-deployed-runtime/how-tos/install-on-kubernetes
**Connector:** Microsoft SQL Server (database)

> Install an App on Kubernetes using Helm charts, Docker images, and specific configuration

:::info **Did you know?** 
SDR requires additional enablement and licensing. Contact your Atlan representative for details.
:::

:::warning Use the guided install wizard instead
**New Self-Deployed Runtime setups are encouraged to use the [guided install wizard](https://docs.atlan.com/product/connections/self-deployed-runtime/how-tos/install-guided).** It assembles a complete guide tailored to your lifecycle mode, platform, and image procurement on a single page—and it's where new setup options (for example, HTTP proxy and custom CA trust) are documented going forward.

This page is kept for existing users who already reference it and may not include the latest steps.
:::

<h2 id="prerequisites">Prerequisites</h2>

Before you begin, make sure you have:

* `kubectl` installed and configured with administrative access to your target Kubernetes cluster
* Helm version 3.0 or later installed on your deployment machine
* A [Docker Hub Personal Access Token (PAT)](https://start.1password.com/open/i?a=WAVUZSKJO5GMNMVBYWAWECXIUE&v=ouvp3xf5334cxoamyiipzjlewy&i=p76avgzmkkcbftldcuvr5jcof4&h=atlanhq.1password.com) from Atlan
* App-specific helm chart name: `{{deploymentValues.helmChartName}}` 
* Object storage: AWS S3, Google Cloud Storage, or Azure Blob Storage with read/write permissions
* Secret store access: AWS Secret Manager, Azure Key Vault, GCP Secret Manager, HashiCorp Vault, or Kubernetes Secrets with read permissions

:::warning For security reasons, the Docker Hub PAT Token is regenerated on a periodic basis. 
In case the token is embedded in automation scripts or CI/CD pipelines, those jobs may fail. 
Contact your Atlan representative for the latest token.
:::

<h2 id="download-required-files">Download required files</h2>

<h3 id="download-helm-chart">Download Helm chart</h3>

Download the Helm chart for the app:

```bash
helm pull oci://registry-1.docker.io/atlanhq/{{deploymentValues.helmChartName}} --untar
```

This unpacks the chart's `Chart.yaml`, `templates/`, and a default `values.yaml` into `./{{deploymentValues.helmChartName}}/`. You'll replace this default `values.yaml` with your Marketplace copy in the next step.

<h3 id="download-values-yaml">Download values.yaml</h3>

Atlan generates the helm `values.yaml` for your runtime directly from the Marketplace UI, including the OAuth client credentials your runtime uses to authenticate to your tenant.

1. Sign in to your Atlan tenant as an administrator, open **Connector** > **Marketplace**, select the app you want to deploy, and click **Download config for Self-Deployed Runtime** in the right-hand sidebar.

2. In the dialog, keep **New deployment** selected (this mints the OAuth client and full config for a fresh runtime), choose **Kubernetes (Helm)** as the deployment target, and enter a **Deployment name**: a short identifier (lowercase letters, digits, and dashes) that identifies this runtime; the agent in **Workflows > Agent** is named `<app_name>-<deployment_name>`.

3. Click **Generate**. Atlan mints a dedicated OAuth client and produces a `values.yaml` file with:
 - `global.atlanBaseUrl`, `global.clientId`, and `global.clientSecret` already filled in.
 - `image.repository`, `image.tag`, and `name` pinned to the active version for your tenant.
 - `objectstore` and `secretstore` placeholders for you to configure below.

<h3 id="replace-chart-values">Replace chart values.yaml</h3>

Replace the default `values.yaml` inside the unpacked chart with the `values.yaml` you downloaded from the Marketplace.

From this point on, all edits to `values.yaml` must be made inside `./{{deploymentValues.helmChartName}}/`.

<h2 id="modify-values-yaml">Modify values.yaml</h2>

### Object storage

Self-Deployed Runtime needs a store for reading or writing files. Configure the object storage that matches your environment:

:::tip Don't see your preferred object store?
If your preferred object store isn't listed here, [reach out to Atlan support](https://docs.atlan.com/support/submit-request). Support for additional object stores may be available.
:::

<Tabs>
<TabItem value="aws-s3" label="AWS S3" default>

**Required permissions:**

Apply object-level actions to `arn:aws:s3:::BUCKET/*` and the list action to `arn:aws:s3:::BUCKET` in separate IAM statement entries.

| IAM action | Operations covered |
|---|---|
| `s3:GetObject` | GetObject (full and byte-range), HeadObject |
| `s3:PutObject` | PutObject, CreateMultipartUpload, UploadPart, CompleteMultipartUpload |
| `s3:AbortMultipartUpload` | Abort in-flight multipart upload on error (required for streaming write error paths) |
| `s3:DeleteObject` | DeleteObject and DeleteObjects (bulk batch—same IAM action) |
| `s3:ListBucket` | ListObjectsV2—bucket-level permission, not object-level |

```json
{
 "Version": "2012-10-17",
 "Statement": [
 {
 "Effect": "Allow",
 "Action": [
 "s3:GetObject",
 "s3:PutObject",
 "s3:AbortMultipartUpload",
 "s3:DeleteObject"
 ],
 "Resource": "arn:aws:s3:::YOUR-BUCKET/*"
 },
 {
 "Effect": "Allow",
 "Action": "s3:ListBucket",
 "Resource": "arn:aws:s3:::YOUR-BUCKET"
 }
 ]
}
```

**AssumeRole**: when using `assumeRoleArn`, the caller identity additionally needs `sts:AssumeRole` on the target role ARN. The role itself holds the bucket policy described earlier.

**Configure:**

 1. Locate the `objectstore` attribute in `values.yaml`.
 2. Add AWS S3 configuration. For more information, see [AWS S3 Binding Spec](https://docs.dapr.io/reference/components-reference/supported-bindings/s3/).

 ```yaml
 objectstore:
 enabled: true
 spec:
 type: bindings.aws.s3
 version: v1
 metadata:
 - name: accessKey #optional, leave this empty for iam authentication
 value: ""
 - name: secretKey #optional, leave this empty for iam authentication
 value: ""
 - name: bucket #required, name of the bucket where application can write
 value: "<bucket-name>"
 - name: region #required, region of the bucket where application can write
 value: "<bucket-region>"
 - name: forcePathStyle
 value: "true"
 ```

</TabItem>
<TabItem value="gcp-storage" label="Google Cloud Storage">

**Required permissions:**

| IAM permission | Operations covered |
|---|---|
| `storage.objects.get` | GetObject (full and byte-range), object metadata / HeadObject equivalent |
| `storage.objects.create` | PutObject, resumable / streaming write |
| `storage.objects.delete` | DeleteObject (GCS has no native bulk-delete API—`delete_prefix` issues parallel single-object deletes) |
| `storage.objects.list` | ListObjects |

No `storage.buckets.*` permissions are needed. The smallest predefined role that covers all four is **`roles/storage.objectAdmin`** scoped to the bucket. Alternatively, create a custom role with exactly these four permissions.

**Configure:**

 1. Locate the `objectstore` attribute in `values.yaml`.
 2. Add Google Cloud Storage configuration. For more information, see [GCP Storage Bucket binding spec](https://docs.dapr.io/reference/components-reference/supported-bindings/gcpbucket/)

 ```yaml
 objectstore:
 enabled: true
 spec:
 type: bindings.gcp.bucket
 version: v1
 metadata:
 - name: bucket
 value: "your-gcs-bucket-name"
 - name: type
 value: "service_account"
 - name: project_id
 value: "your-gcp-project-id"
 ```

</TabItem>
<TabItem value="azure-blob" label="Azure Blob Storage">

**Required permissions:**

**RBAC**—assign at container or storage-account scope:

| RBAC action | Operations covered |
|---|---|
| `Microsoft.Storage/storageAccounts/blobServices/containers/blobs/read` | GetBlob, GetBlobProperties (HEAD), ListBlobs, byte-range GET |
| `Microsoft.Storage/storageAccounts/blobServices/containers/blobs/write` | PutBlob, PutBlock + PutBlockList (streaming / block write) |
| `Microsoft.Storage/storageAccounts/blobServices/containers/blobs/delete` | DeleteBlob, BlobBatch delete (bulk—up to 256 keys per request) |

The smallest predefined role covering all three is **`Storage Blob Data Contributor`**. `Storage Blob Data Owner` is a superset and is only needed if you additionally require POSIX ACL management on ADLS Gen2.

**SAS token**—minimum permissions at container scope: `r` (read) + `w` (write) + `d` (delete) + `l` (list), that is a container-scoped SAS with **`rwdl`**.

**ADLS Gen2 with POSIX ACLs**: if the storage account has hierarchical namespace enabled and you use ACL-based access control instead of RBAC, the principal needs Execute (`X`) on every parent directory and Read / Write / Delete on the objects in scope. RBAC (`Storage Blob Data Contributor`) is simpler and is recommended unless you have a specific ACL requirement.

**Configure:**

 1. Locate the `objectstore` attribute in `values.yaml`.
 2. Add Azure Blob Storage configuration. For more information, see [Azure Blob Storage binding spec](https://docs.dapr.io/reference/components-reference/supported-bindings/blobstorage/)

 ```yaml
 objectstore:
 enabled: true
 spec:
 type: bindings.azure.blobstorage
 version: v1
 metadata:
 - name: accountName
 value: "your-storage-account-name"
 - name: accountKey
 value: "your-storage-account-key"
 - name: containerName
 value: "your-container-name"
 ```

</TabItem>
</Tabs>

### Secret storage

Self-Deployed Runtime fetches secrets from a secret store to connect to the source systems. The secret store references are used to configure the workflow. Configure the secret store that aligns with your security infrastructure:

:::info Did you know?
Dapr supports additional secret stores which aren't mentioned here. For more information, see [Dapr secret store documentation](https://docs.dapr.io/reference/components-reference/supported-secret-stores/) for other configurations.
:::

:::warning Secret content format and naming
When storing credentials, follow the [secret naming and format requirements](https://docs.atlan.com/product/connections/self-deployed-runtime/how-tos/configure-workflow-execution#secret-content-format).
:::

<Tabs>
<TabItem value="aws-secret-manager" label="AWS Secret Manager" default>
 
 1. Locate the `secretstore` attribute in `values.yaml`.
 2. Add AWS Secret Manager configuration. For more information, see [AWS Secrets Manager](https://docs.dapr.io/reference/components-reference/supported-secret-stores/aws-secret-manager/)

 ```yaml
 secretstore:
 enabled: true
 spec:
 type: secretstores.aws.secretmanager
 version: v1
 metadata:
 - name: region # required, region in which secret is hosted
 value: <secret-region>
 # Needed if IAM authentication is not used
 - name: accessKey
 value: ""
 - name: secretKey
 value: ""
 ```

If you are using IAM role / IRSA authentication, leave `accessKey` and `secretKey` empty.

If you are using an IAM user instead, set:
- `accessKey` to the IAM user's access key ID
- `secretKey` to the IAM user's secret access key

That IAM user must have permission to read the target secret from AWS Secrets Manager:

```json
{
 "Version": "2012-10-17",
 "Statement": [
 {
 "Effect": "Allow",
 "Action": [
 "secretsmanager:GetSecretValue",
 "secretsmanager:DescribeSecret"
 ],
 "Resource": "arn:aws:secretsmanager:<region>:<account-id>:secret:<secret-name>*"
 }
 ]
}
```

:::note
Include the trailing `*` in the secret ARN. AWS appends a random suffix to secret names in the ARN, so omitting it can cause access failures.
:::

</TabItem>
<TabItem value="azure-key-vault" label="Azure Key Vault">

 1. Locate the `secretstore` attribute in `values.yaml`.
 2. Add Azure Key Vault configuration. For more information, see [Azure Key Vault secret store](https://docs.dapr.io/reference/components-reference/supported-secret-stores/azure-keyvault/)

 ```yaml
 secretstore:
 enabled: true
 spec:
 type: secretstores.azure.keyvault
 version: v1
 metadata:
 - name: vaultName
 value: "<your-keyvault-name>"
 - name: azureTenantId
 value: "<your-tenant-id>"
 - name: azureClientId
 value: "<your-client-id>"
 - name: azureClientSecret
 value: "<your-client-secret>"
 - name: azureEnvironment
 value: "AZUREPUBLICCLOUD" # Optional: AZUREPUBLICCLOUD, AZURECHINACLOUD, AZUREUSGOVERNMENTCLOUD, AZUREGERMANCLOUD
 ```
 Azure Key Vault supports multiple authentication methods:
 - **Client Secret**: Use `azureClientSecret` with tenant ID and client ID
 - **Certificate**: Use `azureCertificateFile` instead of client secret
 - **Managed Identity**: Omit authentication fields and use Azure managed identity

 For detailed authentication setup, see the [Authenticating to Azure](https://docs.dapr.io/developing-applications/integrations/azure/azure-authentication/authenticating-azure/) documentation.

</TabItem>
<TabItem value="gcp-secret-manager" label="GCP Secret Manager">

1. Locate the `secretstore` attribute in `values.yaml`.
2. Add Google Cloud Secret Manager configuration. For more information, see [GCP Secret Manager](https://docs.dapr.io/reference/components-reference/supported-secret-stores/gcp-secret-manager/)

 The GCP service account used in this configuration must have the `Secret Manager Secret Accessor` role (`roles/secretmanager.secretAccessor`) on the project where your secrets are stored. The metadata values below come from the service account's JSON key file.

 ```yaml
 secretstore:
 enabled: true
 spec:
 type: secretstores.gcp.secretmanager
 version: v1
 metadata:
 - name: type
 value: "service_account"
 - name: project_id
 value: "<project-id>"
 - name: private_key_id
 value: "<private-key-id>"
 - name: private_key
 value: "<private-key>"
 - name: client_email
 value: "<client-email>"
 - name: client_id
 value: "<client-id>"
 - name: auth_uri
 value: "https://accounts.google.com/o/oauth2/auth"
 - name: token_uri
 value: "https://oauth2.googleapis.com/token"
 - name: auth_provider_x509_cert_url
 value: "https://www.googleapis.com/oauth2/v1/certs"
 - name: client_x509_cert_url
 value: "https://www.googleapis.com/robot/v1/metadata/x509/<client-email>"
 ```

</TabItem>
<TabItem value="hashicorp-vault" label="HashiCorp Vault">

1. Locate the `secretstore` attribute in `values.yaml`.
2. Add HashiCorp Vault configuration. For more information, see [HashiCorp Vault](https://docs.dapr.io/reference/components-reference/supported-secret-stores/hashicorp-vault/)

 ```yaml
 secretstore:
 enabled: true
 spec:
 type: secretstores.hashicorp.vault
 version: v1
 metadata:
 - name: vaultAddr
 value: "[vault_address]" # Optional. Default: "https://127.0.0.1:8200"
 - name: caCert # Optional. This or caPath or caPem
 value: "[ca_cert]"
 - name: caPath # Optional. This or CaCert or caPem
 value: "[path_to_ca_cert_file]"
 - name: caPem # Optional. This or CaCert or CaPath
 value: "[encoded_ca_cert_pem]"
 - name: skipVerify # Optional. Default: false
 value: "[skip_tls_verification]"
 - name: tlsServerName # Optional.
 value: "[tls_config_server_name]"
 - name: vaultTokenMountPath # Required if vaultToken not provided. Path to token file.
 value: "[path_to_file_containing_token]"
 - name: vaultToken # Required if vaultTokenMountPath not provided. Token value.
 value: "[vault_token]"
 - name: vaultKVPrefix # Optional. Default: "dapr"
 value: "[vault_prefix]"
 - name: vaultKVUsePrefix # Optional. default: "true"
 value: "[true/false]"
 - name: enginePath # Optional. default: "secret"
 value: "secret"
 - name: vaultValueType # Optional. default: "map"
 value: "map"
 ```

</TabItem>
<TabItem value="kubernetes-secrets" label="Kubernetes Secrets">

1. Locate the `secretstore` attribute in `values.yaml`.
2. Add Kubernetes native secret storage. For more information, see [Kubernetes secrets](https://docs.dapr.io/reference/components-reference/supported-secret-stores/kubernetes-secret-store/)

 ```yaml
 secretstore:
 enabled: true
 spec:
 type: secretstores.kubernetes
 version: v1
 metadata:
 - name: defaultNamespace
 value: "default" # Optional: Default namespace to retrieve secrets from
 - name: kubeconfigPath
 value: "/path/to/kubeconfig" # Optional: Path to kubeconfig file
 ```
 When Dapr is deployed to a Kubernetes cluster, a secret store with the name `kubernetes` is automatically provisioned. You can use this native Kubernetes secret store with no need to create, deploy or maintain a component configuration file.

</TabItem>
<TabItem value="environment-variable-based" label="Environment Variables">

1. Locate the `secretstore` attribute in `values.yaml`.
2. Add Local environment variables as the spec. For more information, see [Local Environment Variables](https://docs.dapr.io/reference/components-reference/supported-secret-stores/envvar-secret-store/)

 ```yaml
 secretstore:
 enabled: true
 spec:
 type: secretstores.local.env
 version: v1
 ```

</TabItem>
</Tabs>

### Image source

Choose how the cluster pulls the app image. Most installs use Atlan's Docker Hub directly; mirror to a private registry if your organization requires it.

<Tabs>
<TabItem value="docker-hub" label="Public Docker Hub" default>

The chart pulls the app image from Atlan's Docker Hub at runtime. The pod needs a Kubernetes secret containing your Docker Hub PAT to authenticate:

```bash
kubectl create secret docker-registry atlan-docker-secret \
 --docker-server=docker.io \
 --docker-username=YOUR_USERNAME \
 --docker-password=YOUR_PAT_TOKEN \
 -n <namespace>
```

- Replace `YOUR_USERNAME` with the Docker Hub username provided by Atlan.
- Replace `YOUR_PAT_TOKEN` with the Personal Access Token (PAT) provided by Atlan.
- Replace `<namespace>` with the namespace you need to install the chart into. The secret and the release must live in the same namespace, or the pod fails with `ImagePullBackOff`.

The downloaded `values.yaml` already references this secret under `imagePullSecrets`. If you use a different secret name, update that field in the file.

</TabItem>
<TabItem value="private-registry" label="Private image repo">

Mirror the Atlan image to your enterprise registry and update `values.yaml` to point at it.

1. Authenticate with Docker Hub using the PAT from Atlan, then pull the source image. The image and tag come from `image.repository` and `image.tag` in the downloaded `values.yaml`:

 ```bash
 docker login -u atlanhq
 # When prompted for password, enter the PAT provided by Atlan
 docker pull <image.repository>:<image.tag>
 ```

2. Push the image to your enterprise's registry. Note down the new repository name and image tag.

3. Update `image.repository` and `image.tag` in `values.yaml` with the new values.

4. If your private registry requires authentication, create an image-pull secret in the target namespace and set `imagePullSecrets` in `values.yaml` to its name.

</TabItem>
</Tabs>

<h2 id="deploy-app">Deploy app</h2>

Follow these steps to deploy the secure app:

* Install the helm chart. The chart directory now carries your edited `values.yaml`, so no `-f` flag is needed:

 ```bash
 helm install {{deploymentValues.helmChartName}}-release ./{{deploymentValues.helmChartName}} -n <namespace>
 ```

 - Replace `<namespace>` with your target Kubernetes namespace.
 - The helm chart name `{{deploymentValues.helmChartName}}` is automatically used from your selected app.

The deployment process typically takes a few minutes to complete depending on factors like Kubernetes cluster resource availability, private image repository download time etc.

<h2 id="verify-app">Verify app</h2>

Follow these steps to verify deployment:

### Verify deployment status on cluster

1. Check pod status:

 ```bash
 kubectl get pods -n <namespace>
 ```

 The output appears similar to:

 ```
 NAME READY STATUS RESTARTS AGE
 <helm-chart-name>-release-<helm-chart-name>-5dff95cd85-cvk5z 1/1 Running 0 2m
 ```
 
 Replace `<helm-chart-name>` with your app's helm chart name (shown in the prerequisites section earlier in this guide).

 The pod status shows `Running` with `1/1` ready containers.

2. Verify logs for the running pod
 
 ```bash
 kubectl logs -n <namespace> -l app.kubernetes.io/name={{deploymentValues.helmChartName}} --tail=50 -f
 ```
 **Example application logs**: Look for these key log messages that confirm successful deployment:

 * `Uvicorn running on http://0.0.0.0:8000` - Web server started
 * `Workflow engine initialized` - Workflow processing ready
 * `dapr initialized. Status: Running` - Dapr runtime active
 * `Starting worker with task queue: atlan-<package-name>-DEPLOYMENT_NAME` - Worker process started (replace `<package-name>` with your app's package name)
 * `GET /server/ready 200` - Health check endpoint responding

### Verify registration via Atlan UI

Once the App is successfully deployed, it communicates to the Atlan tenant and registers itself. Verify App registration is successful in Atlan:

1. In the same Atlan tenant, navigate to **Workflows** > **Agent**.
2. Look for an entry named `<app_name>-<deployment_name>`, where `<app_name>` matches your selected app (for example, "Oracle" or "Microsoft SQL Server") and `<deployment_name>` is the deployment name you entered when generating the config.
3. Confirm the agent status displays as **Active**.

Agent registration and status takes a couple of minutes to reflect in the Atlan UI.

<h2 id="next-steps">Next steps</h2>

* [Configure workflow execution](https://docs.atlan.com/product/connections/self-deployed-runtime/how-tos/configure-workflow-execution): Set up workflow execution with secret retrieval for your Self-deployed Runtime

---

## Install on Kubernetes - MongoDB (self-managed)

URL: https://docs.atlan.com/product/connections/self-deployed-runtime/how-tos/install-on-kubernetes
**Connector:** MongoDB (self-managed) (database)

> Install an App on Kubernetes using Helm charts, Docker images, and specific configuration

:::info **Did you know?** 
SDR requires additional enablement and licensing. Contact your Atlan representative for details.
:::

:::warning Use the guided install wizard instead
**New Self-Deployed Runtime setups are encouraged to use the [guided install wizard](https://docs.atlan.com/product/connections/self-deployed-runtime/how-tos/install-guided).** It assembles a complete guide tailored to your lifecycle mode, platform, and image procurement on a single page—and it's where new setup options (for example, HTTP proxy and custom CA trust) are documented going forward.

This page is kept for existing users who already reference it and may not include the latest steps.
:::

<h2 id="prerequisites">Prerequisites</h2>

Before you begin, make sure you have:

* `kubectl` installed and configured with administrative access to your target Kubernetes cluster
* Helm version 3.0 or later installed on your deployment machine
* A [Docker Hub Personal Access Token (PAT)](https://start.1password.com/open/i?a=WAVUZSKJO5GMNMVBYWAWECXIUE&v=ouvp3xf5334cxoamyiipzjlewy&i=p76avgzmkkcbftldcuvr5jcof4&h=atlanhq.1password.com) from Atlan
* App-specific helm chart name: `{{deploymentValues.helmChartName}}` 
* Object storage: AWS S3, Google Cloud Storage, or Azure Blob Storage with read/write permissions
* Secret store access: AWS Secret Manager, Azure Key Vault, GCP Secret Manager, HashiCorp Vault, or Kubernetes Secrets with read permissions

:::warning For security reasons, the Docker Hub PAT Token is regenerated on a periodic basis. 
In case the token is embedded in automation scripts or CI/CD pipelines, those jobs may fail. 
Contact your Atlan representative for the latest token.
:::

<h2 id="download-required-files">Download required files</h2>

<h3 id="download-helm-chart">Download Helm chart</h3>

Download the Helm chart for the app:

```bash
helm pull oci://registry-1.docker.io/atlanhq/{{deploymentValues.helmChartName}} --untar
```

This unpacks the chart's `Chart.yaml`, `templates/`, and a default `values.yaml` into `./{{deploymentValues.helmChartName}}/`. You'll replace this default `values.yaml` with your Marketplace copy in the next step.

<h3 id="download-values-yaml">Download values.yaml</h3>

Atlan generates the helm `values.yaml` for your runtime directly from the Marketplace UI, including the OAuth client credentials your runtime uses to authenticate to your tenant.

1. Sign in to your Atlan tenant as an administrator, open **Connector** > **Marketplace**, select the app you want to deploy, and click **Download config for Self-Deployed Runtime** in the right-hand sidebar.

2. In the dialog, keep **New deployment** selected (this mints the OAuth client and full config for a fresh runtime), choose **Kubernetes (Helm)** as the deployment target, and enter a **Deployment name**: a short identifier (lowercase letters, digits, and dashes) that identifies this runtime; the agent in **Workflows > Agent** is named `<app_name>-<deployment_name>`.

3. Click **Generate**. Atlan mints a dedicated OAuth client and produces a `values.yaml` file with:
 - `global.atlanBaseUrl`, `global.clientId`, and `global.clientSecret` already filled in.
 - `image.repository`, `image.tag`, and `name` pinned to the active version for your tenant.
 - `objectstore` and `secretstore` placeholders for you to configure below.

<h3 id="replace-chart-values">Replace chart values.yaml</h3>

Replace the default `values.yaml` inside the unpacked chart with the `values.yaml` you downloaded from the Marketplace.

From this point on, all edits to `values.yaml` must be made inside `./{{deploymentValues.helmChartName}}/`.

<h2 id="modify-values-yaml">Modify values.yaml</h2>

### Object storage

Self-Deployed Runtime needs a store for reading or writing files. Configure the object storage that matches your environment:

:::tip Don't see your preferred object store?
If your preferred object store isn't listed here, [reach out to Atlan support](https://docs.atlan.com/support/submit-request). Support for additional object stores may be available.
:::

<Tabs>
<TabItem value="aws-s3" label="AWS S3" default>

**Required permissions:**

Apply object-level actions to `arn:aws:s3:::BUCKET/*` and the list action to `arn:aws:s3:::BUCKET` in separate IAM statement entries.

| IAM action | Operations covered |
|---|---|
| `s3:GetObject` | GetObject (full and byte-range), HeadObject |
| `s3:PutObject` | PutObject, CreateMultipartUpload, UploadPart, CompleteMultipartUpload |
| `s3:AbortMultipartUpload` | Abort in-flight multipart upload on error (required for streaming write error paths) |
| `s3:DeleteObject` | DeleteObject and DeleteObjects (bulk batch—same IAM action) |
| `s3:ListBucket` | ListObjectsV2—bucket-level permission, not object-level |

```json
{
 "Version": "2012-10-17",
 "Statement": [
 {
 "Effect": "Allow",
 "Action": [
 "s3:GetObject",
 "s3:PutObject",
 "s3:AbortMultipartUpload",
 "s3:DeleteObject"
 ],
 "Resource": "arn:aws:s3:::YOUR-BUCKET/*"
 },
 {
 "Effect": "Allow",
 "Action": "s3:ListBucket",
 "Resource": "arn:aws:s3:::YOUR-BUCKET"
 }
 ]
}
```

**AssumeRole**: when using `assumeRoleArn`, the caller identity additionally needs `sts:AssumeRole` on the target role ARN. The role itself holds the bucket policy described earlier.

**Configure:**

 1. Locate the `objectstore` attribute in `values.yaml`.
 2. Add AWS S3 configuration. For more information, see [AWS S3 Binding Spec](https://docs.dapr.io/reference/components-reference/supported-bindings/s3/).

 ```yaml
 objectstore:
 enabled: true
 spec:
 type: bindings.aws.s3
 version: v1
 metadata:
 - name: accessKey #optional, leave this empty for iam authentication
 value: ""
 - name: secretKey #optional, leave this empty for iam authentication
 value: ""
 - name: bucket #required, name of the bucket where application can write
 value: "<bucket-name>"
 - name: region #required, region of the bucket where application can write
 value: "<bucket-region>"
 - name: forcePathStyle
 value: "true"
 ```

</TabItem>
<TabItem value="gcp-storage" label="Google Cloud Storage">

**Required permissions:**

| IAM permission | Operations covered |
|---|---|
| `storage.objects.get` | GetObject (full and byte-range), object metadata / HeadObject equivalent |
| `storage.objects.create` | PutObject, resumable / streaming write |
| `storage.objects.delete` | DeleteObject (GCS has no native bulk-delete API—`delete_prefix` issues parallel single-object deletes) |
| `storage.objects.list` | ListObjects |

No `storage.buckets.*` permissions are needed. The smallest predefined role that covers all four is **`roles/storage.objectAdmin`** scoped to the bucket. Alternatively, create a custom role with exactly these four permissions.

**Configure:**

 1. Locate the `objectstore` attribute in `values.yaml`.
 2. Add Google Cloud Storage configuration. For more information, see [GCP Storage Bucket binding spec](https://docs.dapr.io/reference/components-reference/supported-bindings/gcpbucket/)

 ```yaml
 objectstore:
 enabled: true
 spec:
 type: bindings.gcp.bucket
 version: v1
 metadata:
 - name: bucket
 value: "your-gcs-bucket-name"
 - name: type
 value: "service_account"
 - name: project_id
 value: "your-gcp-project-id"
 ```

</TabItem>
<TabItem value="azure-blob" label="Azure Blob Storage">

**Required permissions:**

**RBAC**—assign at container or storage-account scope:

| RBAC action | Operations covered |
|---|---|
| `Microsoft.Storage/storageAccounts/blobServices/containers/blobs/read` | GetBlob, GetBlobProperties (HEAD), ListBlobs, byte-range GET |
| `Microsoft.Storage/storageAccounts/blobServices/containers/blobs/write` | PutBlob, PutBlock + PutBlockList (streaming / block write) |
| `Microsoft.Storage/storageAccounts/blobServices/containers/blobs/delete` | DeleteBlob, BlobBatch delete (bulk—up to 256 keys per request) |

The smallest predefined role covering all three is **`Storage Blob Data Contributor`**. `Storage Blob Data Owner` is a superset and is only needed if you additionally require POSIX ACL management on ADLS Gen2.

**SAS token**—minimum permissions at container scope: `r` (read) + `w` (write) + `d` (delete) + `l` (list), that is a container-scoped SAS with **`rwdl`**.

**ADLS Gen2 with POSIX ACLs**: if the storage account has hierarchical namespace enabled and you use ACL-based access control instead of RBAC, the principal needs Execute (`X`) on every parent directory and Read / Write / Delete on the objects in scope. RBAC (`Storage Blob Data Contributor`) is simpler and is recommended unless you have a specific ACL requirement.

**Configure:**

 1. Locate the `objectstore` attribute in `values.yaml`.
 2. Add Azure Blob Storage configuration. For more information, see [Azure Blob Storage binding spec](https://docs.dapr.io/reference/components-reference/supported-bindings/blobstorage/)

 ```yaml
 objectstore:
 enabled: true
 spec:
 type: bindings.azure.blobstorage
 version: v1
 metadata:
 - name: accountName
 value: "your-storage-account-name"
 - name: accountKey
 value: "your-storage-account-key"
 - name: containerName
 value: "your-container-name"
 ```

</TabItem>
</Tabs>

### Secret storage

Self-Deployed Runtime fetches secrets from a secret store to connect to the source systems. The secret store references are used to configure the workflow. Configure the secret store that aligns with your security infrastructure:

:::info Did you know?
Dapr supports additional secret stores which aren't mentioned here. For more information, see [Dapr secret store documentation](https://docs.dapr.io/reference/components-reference/supported-secret-stores/) for other configurations.
:::

:::warning Secret content format and naming
When storing credentials, follow the [secret naming and format requirements](https://docs.atlan.com/product/connections/self-deployed-runtime/how-tos/configure-workflow-execution#secret-content-format).
:::

<Tabs>
<TabItem value="aws-secret-manager" label="AWS Secret Manager" default>
 
 1. Locate the `secretstore` attribute in `values.yaml`.
 2. Add AWS Secret Manager configuration. For more information, see [AWS Secrets Manager](https://docs.dapr.io/reference/components-reference/supported-secret-stores/aws-secret-manager/)

 ```yaml
 secretstore:
 enabled: true
 spec:
 type: secretstores.aws.secretmanager
 version: v1
 metadata:
 - name: region # required, region in which secret is hosted
 value: <secret-region>
 # Needed if IAM authentication is not used
 - name: accessKey
 value: ""
 - name: secretKey
 value: ""
 ```

If you are using IAM role / IRSA authentication, leave `accessKey` and `secretKey` empty.

If you are using an IAM user instead, set:
- `accessKey` to the IAM user's access key ID
- `secretKey` to the IAM user's secret access key

That IAM user must have permission to read the target secret from AWS Secrets Manager:

```json
{
 "Version": "2012-10-17",
 "Statement": [
 {
 "Effect": "Allow",
 "Action": [
 "secretsmanager:GetSecretValue",
 "secretsmanager:DescribeSecret"
 ],
 "Resource": "arn:aws:secretsmanager:<region>:<account-id>:secret:<secret-name>*"
 }
 ]
}
```

:::note
Include the trailing `*` in the secret ARN. AWS appends a random suffix to secret names in the ARN, so omitting it can cause access failures.
:::

</TabItem>
<TabItem value="azure-key-vault" label="Azure Key Vault">

 1. Locate the `secretstore` attribute in `values.yaml`.
 2. Add Azure Key Vault configuration. For more information, see [Azure Key Vault secret store](https://docs.dapr.io/reference/components-reference/supported-secret-stores/azure-keyvault/)

 ```yaml
 secretstore:
 enabled: true
 spec:
 type: secretstores.azure.keyvault
 version: v1
 metadata:
 - name: vaultName
 value: "<your-keyvault-name>"
 - name: azureTenantId
 value: "<your-tenant-id>"
 - name: azureClientId
 value: "<your-client-id>"
 - name: azureClientSecret
 value: "<your-client-secret>"
 - name: azureEnvironment
 value: "AZUREPUBLICCLOUD" # Optional: AZUREPUBLICCLOUD, AZURECHINACLOUD, AZUREUSGOVERNMENTCLOUD, AZUREGERMANCLOUD
 ```
 Azure Key Vault supports multiple authentication methods:
 - **Client Secret**: Use `azureClientSecret` with tenant ID and client ID
 - **Certificate**: Use `azureCertificateFile` instead of client secret
 - **Managed Identity**: Omit authentication fields and use Azure managed identity

 For detailed authentication setup, see the [Authenticating to Azure](https://docs.dapr.io/developing-applications/integrations/azure/azure-authentication/authenticating-azure/) documentation.

</TabItem>
<TabItem value="gcp-secret-manager" label="GCP Secret Manager">

1. Locate the `secretstore` attribute in `values.yaml`.
2. Add Google Cloud Secret Manager configuration. For more information, see [GCP Secret Manager](https://docs.dapr.io/reference/components-reference/supported-secret-stores/gcp-secret-manager/)

 The GCP service account used in this configuration must have the `Secret Manager Secret Accessor` role (`roles/secretmanager.secretAccessor`) on the project where your secrets are stored. The metadata values below come from the service account's JSON key file.

 ```yaml
 secretstore:
 enabled: true
 spec:
 type: secretstores.gcp.secretmanager
 version: v1
 metadata:
 - name: type
 value: "service_account"
 - name: project_id
 value: "<project-id>"
 - name: private_key_id
 value: "<private-key-id>"
 - name: private_key
 value: "<private-key>"
 - name: client_email
 value: "<client-email>"
 - name: client_id
 value: "<client-id>"
 - name: auth_uri
 value: "https://accounts.google.com/o/oauth2/auth"
 - name: token_uri
 value: "https://oauth2.googleapis.com/token"
 - name: auth_provider_x509_cert_url
 value: "https://www.googleapis.com/oauth2/v1/certs"
 - name: client_x509_cert_url
 value: "https://www.googleapis.com/robot/v1/metadata/x509/<client-email>"
 ```

</TabItem>
<TabItem value="hashicorp-vault" label="HashiCorp Vault">

1. Locate the `secretstore` attribute in `values.yaml`.
2. Add HashiCorp Vault configuration. For more information, see [HashiCorp Vault](https://docs.dapr.io/reference/components-reference/supported-secret-stores/hashicorp-vault/)

 ```yaml
 secretstore:
 enabled: true
 spec:
 type: secretstores.hashicorp.vault
 version: v1
 metadata:
 - name: vaultAddr
 value: "[vault_address]" # Optional. Default: "https://127.0.0.1:8200"
 - name: caCert # Optional. This or caPath or caPem
 value: "[ca_cert]"
 - name: caPath # Optional. This or CaCert or caPem
 value: "[path_to_ca_cert_file]"
 - name: caPem # Optional. This or CaCert or CaPath
 value: "[encoded_ca_cert_pem]"
 - name: skipVerify # Optional. Default: false
 value: "[skip_tls_verification]"
 - name: tlsServerName # Optional.
 value: "[tls_config_server_name]"
 - name: vaultTokenMountPath # Required if vaultToken not provided. Path to token file.
 value: "[path_to_file_containing_token]"
 - name: vaultToken # Required if vaultTokenMountPath not provided. Token value.
 value: "[vault_token]"
 - name: vaultKVPrefix # Optional. Default: "dapr"
 value: "[vault_prefix]"
 - name: vaultKVUsePrefix # Optional. default: "true"
 value: "[true/false]"
 - name: enginePath # Optional. default: "secret"
 value: "secret"
 - name: vaultValueType # Optional. default: "map"
 value: "map"
 ```

</TabItem>
<TabItem value="kubernetes-secrets" label="Kubernetes Secrets">

1. Locate the `secretstore` attribute in `values.yaml`.
2. Add Kubernetes native secret storage. For more information, see [Kubernetes secrets](https://docs.dapr.io/reference/components-reference/supported-secret-stores/kubernetes-secret-store/)

 ```yaml
 secretstore:
 enabled: true
 spec:
 type: secretstores.kubernetes
 version: v1
 metadata:
 - name: defaultNamespace
 value: "default" # Optional: Default namespace to retrieve secrets from
 - name: kubeconfigPath
 value: "/path/to/kubeconfig" # Optional: Path to kubeconfig file
 ```
 When Dapr is deployed to a Kubernetes cluster, a secret store with the name `kubernetes` is automatically provisioned. You can use this native Kubernetes secret store with no need to create, deploy or maintain a component configuration file.

</TabItem>
<TabItem value="environment-variable-based" label="Environment Variables">

1. Locate the `secretstore` attribute in `values.yaml`.
2. Add Local environment variables as the spec. For more information, see [Local Environment Variables](https://docs.dapr.io/reference/components-reference/supported-secret-stores/envvar-secret-store/)

 ```yaml
 secretstore:
 enabled: true
 spec:
 type: secretstores.local.env
 version: v1
 ```

</TabItem>
</Tabs>

### Image source

Choose how the cluster pulls the app image. Most installs use Atlan's Docker Hub directly; mirror to a private registry if your organization requires it.

<Tabs>
<TabItem value="docker-hub" label="Public Docker Hub" default>

The chart pulls the app image from Atlan's Docker Hub at runtime. The pod needs a Kubernetes secret containing your Docker Hub PAT to authenticate:

```bash
kubectl create secret docker-registry atlan-docker-secret \
 --docker-server=docker.io \
 --docker-username=YOUR_USERNAME \
 --docker-password=YOUR_PAT_TOKEN \
 -n <namespace>
```

- Replace `YOUR_USERNAME` with the Docker Hub username provided by Atlan.
- Replace `YOUR_PAT_TOKEN` with the Personal Access Token (PAT) provided by Atlan.
- Replace `<namespace>` with the namespace you need to install the chart into. The secret and the release must live in the same namespace, or the pod fails with `ImagePullBackOff`.

The downloaded `values.yaml` already references this secret under `imagePullSecrets`. If you use a different secret name, update that field in the file.

</TabItem>
<TabItem value="private-registry" label="Private image repo">

Mirror the Atlan image to your enterprise registry and update `values.yaml` to point at it.

1. Authenticate with Docker Hub using the PAT from Atlan, then pull the source image. The image and tag come from `image.repository` and `image.tag` in the downloaded `values.yaml`:

 ```bash
 docker login -u atlanhq
 # When prompted for password, enter the PAT provided by Atlan
 docker pull <image.repository>:<image.tag>
 ```

2. Push the image to your enterprise's registry. Note down the new repository name and image tag.

3. Update `image.repository` and `image.tag` in `values.yaml` with the new values.

4. If your private registry requires authentication, create an image-pull secret in the target namespace and set `imagePullSecrets` in `values.yaml` to its name.

</TabItem>
</Tabs>

<h2 id="deploy-app">Deploy app</h2>

Follow these steps to deploy the secure app:

* Install the helm chart. The chart directory now carries your edited `values.yaml`, so no `-f` flag is needed:

 ```bash
 helm install {{deploymentValues.helmChartName}}-release ./{{deploymentValues.helmChartName}} -n <namespace>
 ```

 - Replace `<namespace>` with your target Kubernetes namespace.
 - The helm chart name `{{deploymentValues.helmChartName}}` is automatically used from your selected app.

The deployment process typically takes a few minutes to complete depending on factors like Kubernetes cluster resource availability, private image repository download time etc.

<h2 id="verify-app">Verify app</h2>

Follow these steps to verify deployment:

### Verify deployment status on cluster

1. Check pod status:

 ```bash
 kubectl get pods -n <namespace>
 ```

 The output appears similar to:

 ```
 NAME READY STATUS RESTARTS AGE
 <helm-chart-name>-release-<helm-chart-name>-5dff95cd85-cvk5z 1/1 Running 0 2m
 ```
 
 Replace `<helm-chart-name>` with your app's helm chart name (shown in the prerequisites section earlier in this guide).

 The pod status shows `Running` with `1/1` ready containers.

2. Verify logs for the running pod
 
 ```bash
 kubectl logs -n <namespace> -l app.kubernetes.io/name={{deploymentValues.helmChartName}} --tail=50 -f
 ```
 **Example application logs**: Look for these key log messages that confirm successful deployment:

 * `Uvicorn running on http://0.0.0.0:8000` - Web server started
 * `Workflow engine initialized` - Workflow processing ready
 * `dapr initialized. Status: Running` - Dapr runtime active
 * `Starting worker with task queue: atlan-<package-name>-DEPLOYMENT_NAME` - Worker process started (replace `<package-name>` with your app's package name)
 * `GET /server/ready 200` - Health check endpoint responding

### Verify registration via Atlan UI

Once the App is successfully deployed, it communicates to the Atlan tenant and registers itself. Verify App registration is successful in Atlan:

1. In the same Atlan tenant, navigate to **Workflows** > **Agent**.
2. Look for an entry named `<app_name>-<deployment_name>`, where `<app_name>` matches your selected app (for example, "Oracle" or "Microsoft SQL Server") and `<deployment_name>` is the deployment name you entered when generating the config.
3. Confirm the agent status displays as **Active**.

Agent registration and status takes a couple of minutes to reflect in the Atlan UI.

<h2 id="next-steps">Next steps</h2>

* [Configure workflow execution](https://docs.atlan.com/product/connections/self-deployed-runtime/how-tos/configure-workflow-execution): Set up workflow execution with secret retrieval for your Self-deployed Runtime

---

## Install on Kubernetes - MongoDB Atlas

URL: https://docs.atlan.com/product/connections/self-deployed-runtime/how-tos/install-on-kubernetes
**Connector:** MongoDB Atlas (database)

> Install an App on Kubernetes using Helm charts, Docker images, and specific configuration

:::info **Did you know?** 
SDR requires additional enablement and licensing. Contact your Atlan representative for details.
:::

:::warning Use the guided install wizard instead
**New Self-Deployed Runtime setups are encouraged to use the [guided install wizard](https://docs.atlan.com/product/connections/self-deployed-runtime/how-tos/install-guided).** It assembles a complete guide tailored to your lifecycle mode, platform, and image procurement on a single page—and it's where new setup options (for example, HTTP proxy and custom CA trust) are documented going forward.

This page is kept for existing users who already reference it and may not include the latest steps.
:::

<h2 id="prerequisites">Prerequisites</h2>

Before you begin, make sure you have:

* `kubectl` installed and configured with administrative access to your target Kubernetes cluster
* Helm version 3.0 or later installed on your deployment machine
* A [Docker Hub Personal Access Token (PAT)](https://start.1password.com/open/i?a=WAVUZSKJO5GMNMVBYWAWECXIUE&v=ouvp3xf5334cxoamyiipzjlewy&i=p76avgzmkkcbftldcuvr5jcof4&h=atlanhq.1password.com) from Atlan
* App-specific helm chart name: `{{deploymentValues.helmChartName}}` 
* Object storage: AWS S3, Google Cloud Storage, or Azure Blob Storage with read/write permissions
* Secret store access: AWS Secret Manager, Azure Key Vault, GCP Secret Manager, HashiCorp Vault, or Kubernetes Secrets with read permissions

:::warning For security reasons, the Docker Hub PAT Token is regenerated on a periodic basis. 
In case the token is embedded in automation scripts or CI/CD pipelines, those jobs may fail. 
Contact your Atlan representative for the latest token.
:::

<h2 id="download-required-files">Download required files</h2>

<h3 id="download-helm-chart">Download Helm chart</h3>

Download the Helm chart for the app:

```bash
helm pull oci://registry-1.docker.io/atlanhq/{{deploymentValues.helmChartName}} --untar
```

This unpacks the chart's `Chart.yaml`, `templates/`, and a default `values.yaml` into `./{{deploymentValues.helmChartName}}/`. You'll replace this default `values.yaml` with your Marketplace copy in the next step.

<h3 id="download-values-yaml">Download values.yaml</h3>

Atlan generates the helm `values.yaml` for your runtime directly from the Marketplace UI, including the OAuth client credentials your runtime uses to authenticate to your tenant.

1. Sign in to your Atlan tenant as an administrator, open **Connector** > **Marketplace**, select the app you want to deploy, and click **Download config for Self-Deployed Runtime** in the right-hand sidebar.

2. In the dialog, keep **New deployment** selected (this mints the OAuth client and full config for a fresh runtime), choose **Kubernetes (Helm)** as the deployment target, and enter a **Deployment name**: a short identifier (lowercase letters, digits, and dashes) that identifies this runtime; the agent in **Workflows > Agent** is named `<app_name>-<deployment_name>`.

3. Click **Generate**. Atlan mints a dedicated OAuth client and produces a `values.yaml` file with:
 - `global.atlanBaseUrl`, `global.clientId`, and `global.clientSecret` already filled in.
 - `image.repository`, `image.tag`, and `name` pinned to the active version for your tenant.
 - `objectstore` and `secretstore` placeholders for you to configure below.

<h3 id="replace-chart-values">Replace chart values.yaml</h3>

Replace the default `values.yaml` inside the unpacked chart with the `values.yaml` you downloaded from the Marketplace.

From this point on, all edits to `values.yaml` must be made inside `./{{deploymentValues.helmChartName}}/`.

<h2 id="modify-values-yaml">Modify values.yaml</h2>

### Object storage

Self-Deployed Runtime needs a store for reading or writing files. Configure the object storage that matches your environment:

:::tip Don't see your preferred object store?
If your preferred object store isn't listed here, [reach out to Atlan support](https://docs.atlan.com/support/submit-request). Support for additional object stores may be available.
:::

<Tabs>
<TabItem value="aws-s3" label="AWS S3" default>

**Required permissions:**

Apply object-level actions to `arn:aws:s3:::BUCKET/*` and the list action to `arn:aws:s3:::BUCKET` in separate IAM statement entries.

| IAM action | Operations covered |
|---|---|
| `s3:GetObject` | GetObject (full and byte-range), HeadObject |
| `s3:PutObject` | PutObject, CreateMultipartUpload, UploadPart, CompleteMultipartUpload |
| `s3:AbortMultipartUpload` | Abort in-flight multipart upload on error (required for streaming write error paths) |
| `s3:DeleteObject` | DeleteObject and DeleteObjects (bulk batch—same IAM action) |
| `s3:ListBucket` | ListObjectsV2—bucket-level permission, not object-level |

```json
{
 "Version": "2012-10-17",
 "Statement": [
 {
 "Effect": "Allow",
 "Action": [
 "s3:GetObject",
 "s3:PutObject",
 "s3:AbortMultipartUpload",
 "s3:DeleteObject"
 ],
 "Resource": "arn:aws:s3:::YOUR-BUCKET/*"
 },
 {
 "Effect": "Allow",
 "Action": "s3:ListBucket",
 "Resource": "arn:aws:s3:::YOUR-BUCKET"
 }
 ]
}
```

**AssumeRole**: when using `assumeRoleArn`, the caller identity additionally needs `sts:AssumeRole` on the target role ARN. The role itself holds the bucket policy described earlier.

**Configure:**

 1. Locate the `objectstore` attribute in `values.yaml`.
 2. Add AWS S3 configuration. For more information, see [AWS S3 Binding Spec](https://docs.dapr.io/reference/components-reference/supported-bindings/s3/).

 ```yaml
 objectstore:
 enabled: true
 spec:
 type: bindings.aws.s3
 version: v1
 metadata:
 - name: accessKey #optional, leave this empty for iam authentication
 value: ""
 - name: secretKey #optional, leave this empty for iam authentication
 value: ""
 - name: bucket #required, name of the bucket where application can write
 value: "<bucket-name>"
 - name: region #required, region of the bucket where application can write
 value: "<bucket-region>"
 - name: forcePathStyle
 value: "true"
 ```

</TabItem>
<TabItem value="gcp-storage" label="Google Cloud Storage">

**Required permissions:**

| IAM permission | Operations covered |
|---|---|
| `storage.objects.get` | GetObject (full and byte-range), object metadata / HeadObject equivalent |
| `storage.objects.create` | PutObject, resumable / streaming write |
| `storage.objects.delete` | DeleteObject (GCS has no native bulk-delete API—`delete_prefix` issues parallel single-object deletes) |
| `storage.objects.list` | ListObjects |

No `storage.buckets.*` permissions are needed. The smallest predefined role that covers all four is **`roles/storage.objectAdmin`** scoped to the bucket. Alternatively, create a custom role with exactly these four permissions.

**Configure:**

 1. Locate the `objectstore` attribute in `values.yaml`.
 2. Add Google Cloud Storage configuration. For more information, see [GCP Storage Bucket binding spec](https://docs.dapr.io/reference/components-reference/supported-bindings/gcpbucket/)

 ```yaml
 objectstore:
 enabled: true
 spec:
 type: bindings.gcp.bucket
 version: v1
 metadata:
 - name: bucket
 value: "your-gcs-bucket-name"
 - name: type
 value: "service_account"
 - name: project_id
 value: "your-gcp-project-id"
 ```

</TabItem>
<TabItem value="azure-blob" label="Azure Blob Storage">

**Required permissions:**

**RBAC**—assign at container or storage-account scope:

| RBAC action | Operations covered |
|---|---|
| `Microsoft.Storage/storageAccounts/blobServices/containers/blobs/read` | GetBlob, GetBlobProperties (HEAD), ListBlobs, byte-range GET |
| `Microsoft.Storage/storageAccounts/blobServices/containers/blobs/write` | PutBlob, PutBlock + PutBlockList (streaming / block write) |
| `Microsoft.Storage/storageAccounts/blobServices/containers/blobs/delete` | DeleteBlob, BlobBatch delete (bulk—up to 256 keys per request) |

The smallest predefined role covering all three is **`Storage Blob Data Contributor`**. `Storage Blob Data Owner` is a superset and is only needed if you additionally require POSIX ACL management on ADLS Gen2.

**SAS token**—minimum permissions at container scope: `r` (read) + `w` (write) + `d` (delete) + `l` (list), that is a container-scoped SAS with **`rwdl`**.

**ADLS Gen2 with POSIX ACLs**: if the storage account has hierarchical namespace enabled and you use ACL-based access control instead of RBAC, the principal needs Execute (`X`) on every parent directory and Read / Write / Delete on the objects in scope. RBAC (`Storage Blob Data Contributor`) is simpler and is recommended unless you have a specific ACL requirement.

**Configure:**

 1. Locate the `objectstore` attribute in `values.yaml`.
 2. Add Azure Blob Storage configuration. For more information, see [Azure Blob Storage binding spec](https://docs.dapr.io/reference/components-reference/supported-bindings/blobstorage/)

 ```yaml
 objectstore:
 enabled: true
 spec:
 type: bindings.azure.blobstorage
 version: v1
 metadata:
 - name: accountName
 value: "your-storage-account-name"
 - name: accountKey
 value: "your-storage-account-key"
 - name: containerName
 value: "your-container-name"
 ```

</TabItem>
</Tabs>

### Secret storage

Self-Deployed Runtime fetches secrets from a secret store to connect to the source systems. The secret store references are used to configure the workflow. Configure the secret store that aligns with your security infrastructure:

:::info Did you know?
Dapr supports additional secret stores which aren't mentioned here. For more information, see [Dapr secret store documentation](https://docs.dapr.io/reference/components-reference/supported-secret-stores/) for other configurations.
:::

:::warning Secret content format and naming
When storing credentials, follow the [secret naming and format requirements](https://docs.atlan.com/product/connections/self-deployed-runtime/how-tos/configure-workflow-execution#secret-content-format).
:::

<Tabs>
<TabItem value="aws-secret-manager" label="AWS Secret Manager" default>
 
 1. Locate the `secretstore` attribute in `values.yaml`.
 2. Add AWS Secret Manager configuration. For more information, see [AWS Secrets Manager](https://docs.dapr.io/reference/components-reference/supported-secret-stores/aws-secret-manager/)

 ```yaml
 secretstore:
 enabled: true
 spec:
 type: secretstores.aws.secretmanager
 version: v1
 metadata:
 - name: region # required, region in which secret is hosted
 value: <secret-region>
 # Needed if IAM authentication is not used
 - name: accessKey
 value: ""
 - name: secretKey
 value: ""
 ```

If you are using IAM role / IRSA authentication, leave `accessKey` and `secretKey` empty.

If you are using an IAM user instead, set:
- `accessKey` to the IAM user's access key ID
- `secretKey` to the IAM user's secret access key

That IAM user must have permission to read the target secret from AWS Secrets Manager:

```json
{
 "Version": "2012-10-17",
 "Statement": [
 {
 "Effect": "Allow",
 "Action": [
 "secretsmanager:GetSecretValue",
 "secretsmanager:DescribeSecret"
 ],
 "Resource": "arn:aws:secretsmanager:<region>:<account-id>:secret:<secret-name>*"
 }
 ]
}
```

:::note
Include the trailing `*` in the secret ARN. AWS appends a random suffix to secret names in the ARN, so omitting it can cause access failures.
:::

</TabItem>
<TabItem value="azure-key-vault" label="Azure Key Vault">

 1. Locate the `secretstore` attribute in `values.yaml`.
 2. Add Azure Key Vault configuration. For more information, see [Azure Key Vault secret store](https://docs.dapr.io/reference/components-reference/supported-secret-stores/azure-keyvault/)

 ```yaml
 secretstore:
 enabled: true
 spec:
 type: secretstores.azure.keyvault
 version: v1
 metadata:
 - name: vaultName
 value: "<your-keyvault-name>"
 - name: azureTenantId
 value: "<your-tenant-id>"
 - name: azureClientId
 value: "<your-client-id>"
 - name: azureClientSecret
 value: "<your-client-secret>"
 - name: azureEnvironment
 value: "AZUREPUBLICCLOUD" # Optional: AZUREPUBLICCLOUD, AZURECHINACLOUD, AZUREUSGOVERNMENTCLOUD, AZUREGERMANCLOUD
 ```
 Azure Key Vault supports multiple authentication methods:
 - **Client Secret**: Use `azureClientSecret` with tenant ID and client ID
 - **Certificate**: Use `azureCertificateFile` instead of client secret
 - **Managed Identity**: Omit authentication fields and use Azure managed identity

 For detailed authentication setup, see the [Authenticating to Azure](https://docs.dapr.io/developing-applications/integrations/azure/azure-authentication/authenticating-azure/) documentation.

</TabItem>
<TabItem value="gcp-secret-manager" label="GCP Secret Manager">

1. Locate the `secretstore` attribute in `values.yaml`.
2. Add Google Cloud Secret Manager configuration. For more information, see [GCP Secret Manager](https://docs.dapr.io/reference/components-reference/supported-secret-stores/gcp-secret-manager/)

 The GCP service account used in this configuration must have the `Secret Manager Secret Accessor` role (`roles/secretmanager.secretAccessor`) on the project where your secrets are stored. The metadata values below come from the service account's JSON key file.

 ```yaml
 secretstore:
 enabled: true
 spec:
 type: secretstores.gcp.secretmanager
 version: v1
 metadata:
 - name: type
 value: "service_account"
 - name: project_id
 value: "<project-id>"
 - name: private_key_id
 value: "<private-key-id>"
 - name: private_key
 value: "<private-key>"
 - name: client_email
 value: "<client-email>"
 - name: client_id
 value: "<client-id>"
 - name: auth_uri
 value: "https://accounts.google.com/o/oauth2/auth"
 - name: token_uri
 value: "https://oauth2.googleapis.com/token"
 - name: auth_provider_x509_cert_url
 value: "https://www.googleapis.com/oauth2/v1/certs"
 - name: client_x509_cert_url
 value: "https://www.googleapis.com/robot/v1/metadata/x509/<client-email>"
 ```

</TabItem>
<TabItem value="hashicorp-vault" label="HashiCorp Vault">

1. Locate the `secretstore` attribute in `values.yaml`.
2. Add HashiCorp Vault configuration. For more information, see [HashiCorp Vault](https://docs.dapr.io/reference/components-reference/supported-secret-stores/hashicorp-vault/)

 ```yaml
 secretstore:
 enabled: true
 spec:
 type: secretstores.hashicorp.vault
 version: v1
 metadata:
 - name: vaultAddr
 value: "[vault_address]" # Optional. Default: "https://127.0.0.1:8200"
 - name: caCert # Optional. This or caPath or caPem
 value: "[ca_cert]"
 - name: caPath # Optional. This or CaCert or caPem
 value: "[path_to_ca_cert_file]"
 - name: caPem # Optional. This or CaCert or CaPath
 value: "[encoded_ca_cert_pem]"
 - name: skipVerify # Optional. Default: false
 value: "[skip_tls_verification]"
 - name: tlsServerName # Optional.
 value: "[tls_config_server_name]"
 - name: vaultTokenMountPath # Required if vaultToken not provided. Path to token file.
 value: "[path_to_file_containing_token]"
 - name: vaultToken # Required if vaultTokenMountPath not provided. Token value.
 value: "[vault_token]"
 - name: vaultKVPrefix # Optional. Default: "dapr"
 value: "[vault_prefix]"
 - name: vaultKVUsePrefix # Optional. default: "true"
 value: "[true/false]"
 - name: enginePath # Optional. default: "secret"
 value: "secret"
 - name: vaultValueType # Optional. default: "map"
 value: "map"
 ```

</TabItem>
<TabItem value="kubernetes-secrets" label="Kubernetes Secrets">

1. Locate the `secretstore` attribute in `values.yaml`.
2. Add Kubernetes native secret storage. For more information, see [Kubernetes secrets](https://docs.dapr.io/reference/components-reference/supported-secret-stores/kubernetes-secret-store/)

 ```yaml
 secretstore:
 enabled: true
 spec:
 type: secretstores.kubernetes
 version: v1
 metadata:
 - name: defaultNamespace
 value: "default" # Optional: Default namespace to retrieve secrets from
 - name: kubeconfigPath
 value: "/path/to/kubeconfig" # Optional: Path to kubeconfig file
 ```
 When Dapr is deployed to a Kubernetes cluster, a secret store with the name `kubernetes` is automatically provisioned. You can use this native Kubernetes secret store with no need to create, deploy or maintain a component configuration file.

</TabItem>
<TabItem value="environment-variable-based" label="Environment Variables">

1. Locate the `secretstore` attribute in `values.yaml`.
2. Add Local environment variables as the spec. For more information, see [Local Environment Variables](https://docs.dapr.io/reference/components-reference/supported-secret-stores/envvar-secret-store/)

 ```yaml
 secretstore:
 enabled: true
 spec:
 type: secretstores.local.env
 version: v1
 ```

</TabItem>
</Tabs>

### Image source

Choose how the cluster pulls the app image. Most installs use Atlan's Docker Hub directly; mirror to a private registry if your organization requires it.

<Tabs>
<TabItem value="docker-hub" label="Public Docker Hub" default>

The chart pulls the app image from Atlan's Docker Hub at runtime. The pod needs a Kubernetes secret containing your Docker Hub PAT to authenticate:

```bash
kubectl create secret docker-registry atlan-docker-secret \
 --docker-server=docker.io \
 --docker-username=YOUR_USERNAME \
 --docker-password=YOUR_PAT_TOKEN \
 -n <namespace>
```

- Replace `YOUR_USERNAME` with the Docker Hub username provided by Atlan.
- Replace `YOUR_PAT_TOKEN` with the Personal Access Token (PAT) provided by Atlan.
- Replace `<namespace>` with the namespace you need to install the chart into. The secret and the release must live in the same namespace, or the pod fails with `ImagePullBackOff`.

The downloaded `values.yaml` already references this secret under `imagePullSecrets`. If you use a different secret name, update that field in the file.

</TabItem>
<TabItem value="private-registry" label="Private image repo">

Mirror the Atlan image to your enterprise registry and update `values.yaml` to point at it.

1. Authenticate with Docker Hub using the PAT from Atlan, then pull the source image. The image and tag come from `image.repository` and `image.tag` in the downloaded `values.yaml`:

 ```bash
 docker login -u atlanhq
 # When prompted for password, enter the PAT provided by Atlan
 docker pull <image.repository>:<image.tag>
 ```

2. Push the image to your enterprise's registry. Note down the new repository name and image tag.

3. Update `image.repository` and `image.tag` in `values.yaml` with the new values.

4. If your private registry requires authentication, create an image-pull secret in the target namespace and set `imagePullSecrets` in `values.yaml` to its name.

</TabItem>
</Tabs>

<h2 id="deploy-app">Deploy app</h2>

Follow these steps to deploy the secure app:

* Install the helm chart. The chart directory now carries your edited `values.yaml`, so no `-f` flag is needed:

 ```bash
 helm install {{deploymentValues.helmChartName}}-release ./{{deploymentValues.helmChartName}} -n <namespace>
 ```

 - Replace `<namespace>` with your target Kubernetes namespace.
 - The helm chart name `{{deploymentValues.helmChartName}}` is automatically used from your selected app.

The deployment process typically takes a few minutes to complete depending on factors like Kubernetes cluster resource availability, private image repository download time etc.

<h2 id="verify-app">Verify app</h2>

Follow these steps to verify deployment:

### Verify deployment status on cluster

1. Check pod status:

 ```bash
 kubectl get pods -n <namespace>
 ```

 The output appears similar to:

 ```
 NAME READY STATUS RESTARTS AGE
 <helm-chart-name>-release-<helm-chart-name>-5dff95cd85-cvk5z 1/1 Running 0 2m
 ```
 
 Replace `<helm-chart-name>` with your app's helm chart name (shown in the prerequisites section earlier in this guide).

 The pod status shows `Running` with `1/1` ready containers.

2. Verify logs for the running pod
 
 ```bash
 kubectl logs -n <namespace> -l app.kubernetes.io/name={{deploymentValues.helmChartName}} --tail=50 -f
 ```
 **Example application logs**: Look for these key log messages that confirm successful deployment:

 * `Uvicorn running on http://0.0.0.0:8000` - Web server started
 * `Workflow engine initialized` - Workflow processing ready
 * `dapr initialized. Status: Running` - Dapr runtime active
 * `Starting worker with task queue: atlan-<package-name>-DEPLOYMENT_NAME` - Worker process started (replace `<package-name>` with your app's package name)
 * `GET /server/ready 200` - Health check endpoint responding

### Verify registration via Atlan UI

Once the App is successfully deployed, it communicates to the Atlan tenant and registers itself. Verify App registration is successful in Atlan:

1. In the same Atlan tenant, navigate to **Workflows** > **Agent**.
2. Look for an entry named `<app_name>-<deployment_name>`, where `<app_name>` matches your selected app (for example, "Oracle" or "Microsoft SQL Server") and `<deployment_name>` is the deployment name you entered when generating the config.
3. Confirm the agent status displays as **Active**.

Agent registration and status takes a couple of minutes to reflect in the Atlan UI.

<h2 id="next-steps">Next steps</h2>

* [Configure workflow execution](https://docs.atlan.com/product/connections/self-deployed-runtime/how-tos/configure-workflow-execution): Set up workflow execution with secret retrieval for your Self-deployed Runtime

---

## Install on Kubernetes - MySQL

URL: https://docs.atlan.com/product/connections/self-deployed-runtime/how-tos/install-on-kubernetes
**Connector:** MySQL (database)

> Install an App on Kubernetes using Helm charts, Docker images, and specific configuration

:::info **Did you know?** 
SDR requires additional enablement and licensing. Contact your Atlan representative for details.
:::

:::warning Use the guided install wizard instead
**New Self-Deployed Runtime setups are encouraged to use the [guided install wizard](https://docs.atlan.com/product/connections/self-deployed-runtime/how-tos/install-guided).** It assembles a complete guide tailored to your lifecycle mode, platform, and image procurement on a single page—and it's where new setup options (for example, HTTP proxy and custom CA trust) are documented going forward.

This page is kept for existing users who already reference it and may not include the latest steps.
:::

<h2 id="prerequisites">Prerequisites</h2>

Before you begin, make sure you have:

* `kubectl` installed and configured with administrative access to your target Kubernetes cluster
* Helm version 3.0 or later installed on your deployment machine
* A [Docker Hub Personal Access Token (PAT)](https://start.1password.com/open/i?a=WAVUZSKJO5GMNMVBYWAWECXIUE&v=ouvp3xf5334cxoamyiipzjlewy&i=p76avgzmkkcbftldcuvr5jcof4&h=atlanhq.1password.com) from Atlan
* App-specific helm chart name: `{{deploymentValues.helmChartName}}` 
* Object storage: AWS S3, Google Cloud Storage, or Azure Blob Storage with read/write permissions
* Secret store access: AWS Secret Manager, Azure Key Vault, GCP Secret Manager, HashiCorp Vault, or Kubernetes Secrets with read permissions

:::warning For security reasons, the Docker Hub PAT Token is regenerated on a periodic basis. 
In case the token is embedded in automation scripts or CI/CD pipelines, those jobs may fail. 
Contact your Atlan representative for the latest token.
:::

<h2 id="download-required-files">Download required files</h2>

<h3 id="download-helm-chart">Download Helm chart</h3>

Download the Helm chart for the app:

```bash
helm pull oci://registry-1.docker.io/atlanhq/{{deploymentValues.helmChartName}} --untar
```

This unpacks the chart's `Chart.yaml`, `templates/`, and a default `values.yaml` into `./{{deploymentValues.helmChartName}}/`. You'll replace this default `values.yaml` with your Marketplace copy in the next step.

<h3 id="download-values-yaml">Download values.yaml</h3>

Atlan generates the helm `values.yaml` for your runtime directly from the Marketplace UI, including the OAuth client credentials your runtime uses to authenticate to your tenant.

1. Sign in to your Atlan tenant as an administrator, open **Connector** > **Marketplace**, select the app you want to deploy, and click **Download config for Self-Deployed Runtime** in the right-hand sidebar.

2. In the dialog, keep **New deployment** selected (this mints the OAuth client and full config for a fresh runtime), choose **Kubernetes (Helm)** as the deployment target, and enter a **Deployment name**: a short identifier (lowercase letters, digits, and dashes) that identifies this runtime; the agent in **Workflows > Agent** is named `<app_name>-<deployment_name>`.

3. Click **Generate**. Atlan mints a dedicated OAuth client and produces a `values.yaml` file with:
 - `global.atlanBaseUrl`, `global.clientId`, and `global.clientSecret` already filled in.
 - `image.repository`, `image.tag`, and `name` pinned to the active version for your tenant.
 - `objectstore` and `secretstore` placeholders for you to configure below.

<h3 id="replace-chart-values">Replace chart values.yaml</h3>

Replace the default `values.yaml` inside the unpacked chart with the `values.yaml` you downloaded from the Marketplace.

From this point on, all edits to `values.yaml` must be made inside `./{{deploymentValues.helmChartName}}/`.

<h2 id="modify-values-yaml">Modify values.yaml</h2>

### Object storage

Self-Deployed Runtime needs a store for reading or writing files. Configure the object storage that matches your environment:

:::tip Don't see your preferred object store?
If your preferred object store isn't listed here, [reach out to Atlan support](https://docs.atlan.com/support/submit-request). Support for additional object stores may be available.
:::

<Tabs>
<TabItem value="aws-s3" label="AWS S3" default>

**Required permissions:**

Apply object-level actions to `arn:aws:s3:::BUCKET/*` and the list action to `arn:aws:s3:::BUCKET` in separate IAM statement entries.

| IAM action | Operations covered |
|---|---|
| `s3:GetObject` | GetObject (full and byte-range), HeadObject |
| `s3:PutObject` | PutObject, CreateMultipartUpload, UploadPart, CompleteMultipartUpload |
| `s3:AbortMultipartUpload` | Abort in-flight multipart upload on error (required for streaming write error paths) |
| `s3:DeleteObject` | DeleteObject and DeleteObjects (bulk batch—same IAM action) |
| `s3:ListBucket` | ListObjectsV2—bucket-level permission, not object-level |

```json
{
 "Version": "2012-10-17",
 "Statement": [
 {
 "Effect": "Allow",
 "Action": [
 "s3:GetObject",
 "s3:PutObject",
 "s3:AbortMultipartUpload",
 "s3:DeleteObject"
 ],
 "Resource": "arn:aws:s3:::YOUR-BUCKET/*"
 },
 {
 "Effect": "Allow",
 "Action": "s3:ListBucket",
 "Resource": "arn:aws:s3:::YOUR-BUCKET"
 }
 ]
}
```

**AssumeRole**: when using `assumeRoleArn`, the caller identity additionally needs `sts:AssumeRole` on the target role ARN. The role itself holds the bucket policy described earlier.

**Configure:**

 1. Locate the `objectstore` attribute in `values.yaml`.
 2. Add AWS S3 configuration. For more information, see [AWS S3 Binding Spec](https://docs.dapr.io/reference/components-reference/supported-bindings/s3/).

 ```yaml
 objectstore:
 enabled: true
 spec:
 type: bindings.aws.s3
 version: v1
 metadata:
 - name: accessKey #optional, leave this empty for iam authentication
 value: ""
 - name: secretKey #optional, leave this empty for iam authentication
 value: ""
 - name: bucket #required, name of the bucket where application can write
 value: "<bucket-name>"
 - name: region #required, region of the bucket where application can write
 value: "<bucket-region>"
 - name: forcePathStyle
 value: "true"
 ```

</TabItem>
<TabItem value="gcp-storage" label="Google Cloud Storage">

**Required permissions:**

| IAM permission | Operations covered |
|---|---|
| `storage.objects.get` | GetObject (full and byte-range), object metadata / HeadObject equivalent |
| `storage.objects.create` | PutObject, resumable / streaming write |
| `storage.objects.delete` | DeleteObject (GCS has no native bulk-delete API—`delete_prefix` issues parallel single-object deletes) |
| `storage.objects.list` | ListObjects |

No `storage.buckets.*` permissions are needed. The smallest predefined role that covers all four is **`roles/storage.objectAdmin`** scoped to the bucket. Alternatively, create a custom role with exactly these four permissions.

**Configure:**

 1. Locate the `objectstore` attribute in `values.yaml`.
 2. Add Google Cloud Storage configuration. For more information, see [GCP Storage Bucket binding spec](https://docs.dapr.io/reference/components-reference/supported-bindings/gcpbucket/)

 ```yaml
 objectstore:
 enabled: true
 spec:
 type: bindings.gcp.bucket
 version: v1
 metadata:
 - name: bucket
 value: "your-gcs-bucket-name"
 - name: type
 value: "service_account"
 - name: project_id
 value: "your-gcp-project-id"
 ```

</TabItem>
<TabItem value="azure-blob" label="Azure Blob Storage">

**Required permissions:**

**RBAC**—assign at container or storage-account scope:

| RBAC action | Operations covered |
|---|---|
| `Microsoft.Storage/storageAccounts/blobServices/containers/blobs/read` | GetBlob, GetBlobProperties (HEAD), ListBlobs, byte-range GET |
| `Microsoft.Storage/storageAccounts/blobServices/containers/blobs/write` | PutBlob, PutBlock + PutBlockList (streaming / block write) |
| `Microsoft.Storage/storageAccounts/blobServices/containers/blobs/delete` | DeleteBlob, BlobBatch delete (bulk—up to 256 keys per request) |

The smallest predefined role covering all three is **`Storage Blob Data Contributor`**. `Storage Blob Data Owner` is a superset and is only needed if you additionally require POSIX ACL management on ADLS Gen2.

**SAS token**—minimum permissions at container scope: `r` (read) + `w` (write) + `d` (delete) + `l` (list), that is a container-scoped SAS with **`rwdl`**.

**ADLS Gen2 with POSIX ACLs**: if the storage account has hierarchical namespace enabled and you use ACL-based access control instead of RBAC, the principal needs Execute (`X`) on every parent directory and Read / Write / Delete on the objects in scope. RBAC (`Storage Blob Data Contributor`) is simpler and is recommended unless you have a specific ACL requirement.

**Configure:**

 1. Locate the `objectstore` attribute in `values.yaml`.
 2. Add Azure Blob Storage configuration. For more information, see [Azure Blob Storage binding spec](https://docs.dapr.io/reference/components-reference/supported-bindings/blobstorage/)

 ```yaml
 objectstore:
 enabled: true
 spec:
 type: bindings.azure.blobstorage
 version: v1
 metadata:
 - name: accountName
 value: "your-storage-account-name"
 - name: accountKey
 value: "your-storage-account-key"
 - name: containerName
 value: "your-container-name"
 ```

</TabItem>
</Tabs>

### Secret storage

Self-Deployed Runtime fetches secrets from a secret store to connect to the source systems. The secret store references are used to configure the workflow. Configure the secret store that aligns with your security infrastructure:

:::info Did you know?
Dapr supports additional secret stores which aren't mentioned here. For more information, see [Dapr secret store documentation](https://docs.dapr.io/reference/components-reference/supported-secret-stores/) for other configurations.
:::

:::warning Secret content format and naming
When storing credentials, follow the [secret naming and format requirements](https://docs.atlan.com/product/connections/self-deployed-runtime/how-tos/configure-workflow-execution#secret-content-format).
:::

<Tabs>
<TabItem value="aws-secret-manager" label="AWS Secret Manager" default>
 
 1. Locate the `secretstore` attribute in `values.yaml`.
 2. Add AWS Secret Manager configuration. For more information, see [AWS Secrets Manager](https://docs.dapr.io/reference/components-reference/supported-secret-stores/aws-secret-manager/)

 ```yaml
 secretstore:
 enabled: true
 spec:
 type: secretstores.aws.secretmanager
 version: v1
 metadata:
 - name: region # required, region in which secret is hosted
 value: <secret-region>
 # Needed if IAM authentication is not used
 - name: accessKey
 value: ""
 - name: secretKey
 value: ""
 ```

If you are using IAM role / IRSA authentication, leave `accessKey` and `secretKey` empty.

If you are using an IAM user instead, set:
- `accessKey` to the IAM user's access key ID
- `secretKey` to the IAM user's secret access key

That IAM user must have permission to read the target secret from AWS Secrets Manager:

```json
{
 "Version": "2012-10-17",
 "Statement": [
 {
 "Effect": "Allow",
 "Action": [
 "secretsmanager:GetSecretValue",
 "secretsmanager:DescribeSecret"
 ],
 "Resource": "arn:aws:secretsmanager:<region>:<account-id>:secret:<secret-name>*"
 }
 ]
}
```

:::note
Include the trailing `*` in the secret ARN. AWS appends a random suffix to secret names in the ARN, so omitting it can cause access failures.
:::

</TabItem>
<TabItem value="azure-key-vault" label="Azure Key Vault">

 1. Locate the `secretstore` attribute in `values.yaml`.
 2. Add Azure Key Vault configuration. For more information, see [Azure Key Vault secret store](https://docs.dapr.io/reference/components-reference/supported-secret-stores/azure-keyvault/)

 ```yaml
 secretstore:
 enabled: true
 spec:
 type: secretstores.azure.keyvault
 version: v1
 metadata:
 - name: vaultName
 value: "<your-keyvault-name>"
 - name: azureTenantId
 value: "<your-tenant-id>"
 - name: azureClientId
 value: "<your-client-id>"
 - name: azureClientSecret
 value: "<your-client-secret>"
 - name: azureEnvironment
 value: "AZUREPUBLICCLOUD" # Optional: AZUREPUBLICCLOUD, AZURECHINACLOUD, AZUREUSGOVERNMENTCLOUD, AZUREGERMANCLOUD
 ```
 Azure Key Vault supports multiple authentication methods:
 - **Client Secret**: Use `azureClientSecret` with tenant ID and client ID
 - **Certificate**: Use `azureCertificateFile` instead of client secret
 - **Managed Identity**: Omit authentication fields and use Azure managed identity

 For detailed authentication setup, see the [Authenticating to Azure](https://docs.dapr.io/developing-applications/integrations/azure/azure-authentication/authenticating-azure/) documentation.

</TabItem>
<TabItem value="gcp-secret-manager" label="GCP Secret Manager">

1. Locate the `secretstore` attribute in `values.yaml`.
2. Add Google Cloud Secret Manager configuration. For more information, see [GCP Secret Manager](https://docs.dapr.io/reference/components-reference/supported-secret-stores/gcp-secret-manager/)

 The GCP service account used in this configuration must have the `Secret Manager Secret Accessor` role (`roles/secretmanager.secretAccessor`) on the project where your secrets are stored. The metadata values below come from the service account's JSON key file.

 ```yaml
 secretstore:
 enabled: true
 spec:
 type: secretstores.gcp.secretmanager
 version: v1
 metadata:
 - name: type
 value: "service_account"
 - name: project_id
 value: "<project-id>"
 - name: private_key_id
 value: "<private-key-id>"
 - name: private_key
 value: "<private-key>"
 - name: client_email
 value: "<client-email>"
 - name: client_id
 value: "<client-id>"
 - name: auth_uri
 value: "https://accounts.google.com/o/oauth2/auth"
 - name: token_uri
 value: "https://oauth2.googleapis.com/token"
 - name: auth_provider_x509_cert_url
 value: "https://www.googleapis.com/oauth2/v1/certs"
 - name: client_x509_cert_url
 value: "https://www.googleapis.com/robot/v1/metadata/x509/<client-email>"
 ```

</TabItem>
<TabItem value="hashicorp-vault" label="HashiCorp Vault">

1. Locate the `secretstore` attribute in `values.yaml`.
2. Add HashiCorp Vault configuration. For more information, see [HashiCorp Vault](https://docs.dapr.io/reference/components-reference/supported-secret-stores/hashicorp-vault/)

 ```yaml
 secretstore:
 enabled: true
 spec:
 type: secretstores.hashicorp.vault
 version: v1
 metadata:
 - name: vaultAddr
 value: "[vault_address]" # Optional. Default: "https://127.0.0.1:8200"
 - name: caCert # Optional. This or caPath or caPem
 value: "[ca_cert]"
 - name: caPath # Optional. This or CaCert or caPem
 value: "[path_to_ca_cert_file]"
 - name: caPem # Optional. This or CaCert or CaPath
 value: "[encoded_ca_cert_pem]"
 - name: skipVerify # Optional. Default: false
 value: "[skip_tls_verification]"
 - name: tlsServerName # Optional.
 value: "[tls_config_server_name]"
 - name: vaultTokenMountPath # Required if vaultToken not provided. Path to token file.
 value: "[path_to_file_containing_token]"
 - name: vaultToken # Required if vaultTokenMountPath not provided. Token value.
 value: "[vault_token]"
 - name: vaultKVPrefix # Optional. Default: "dapr"
 value: "[vault_prefix]"
 - name: vaultKVUsePrefix # Optional. default: "true"
 value: "[true/false]"
 - name: enginePath # Optional. default: "secret"
 value: "secret"
 - name: vaultValueType # Optional. default: "map"
 value: "map"
 ```

</TabItem>
<TabItem value="kubernetes-secrets" label="Kubernetes Secrets">

1. Locate the `secretstore` attribute in `values.yaml`.
2. Add Kubernetes native secret storage. For more information, see [Kubernetes secrets](https://docs.dapr.io/reference/components-reference/supported-secret-stores/kubernetes-secret-store/)

 ```yaml
 secretstore:
 enabled: true
 spec:
 type: secretstores.kubernetes
 version: v1
 metadata:
 - name: defaultNamespace
 value: "default" # Optional: Default namespace to retrieve secrets from
 - name: kubeconfigPath
 value: "/path/to/kubeconfig" # Optional: Path to kubeconfig file
 ```
 When Dapr is deployed to a Kubernetes cluster, a secret store with the name `kubernetes` is automatically provisioned. You can use this native Kubernetes secret store with no need to create, deploy or maintain a component configuration file.

</TabItem>
<TabItem value="environment-variable-based" label="Environment Variables">

1. Locate the `secretstore` attribute in `values.yaml`.
2. Add Local environment variables as the spec. For more information, see [Local Environment Variables](https://docs.dapr.io/reference/components-reference/supported-secret-stores/envvar-secret-store/)

 ```yaml
 secretstore:
 enabled: true
 spec:
 type: secretstores.local.env
 version: v1
 ```

</TabItem>
</Tabs>

### Image source

Choose how the cluster pulls the app image. Most installs use Atlan's Docker Hub directly; mirror to a private registry if your organization requires it.

<Tabs>
<TabItem value="docker-hub" label="Public Docker Hub" default>

The chart pulls the app image from Atlan's Docker Hub at runtime. The pod needs a Kubernetes secret containing your Docker Hub PAT to authenticate:

```bash
kubectl create secret docker-registry atlan-docker-secret \
 --docker-server=docker.io \
 --docker-username=YOUR_USERNAME \
 --docker-password=YOUR_PAT_TOKEN \
 -n <namespace>
```

- Replace `YOUR_USERNAME` with the Docker Hub username provided by Atlan.
- Replace `YOUR_PAT_TOKEN` with the Personal Access Token (PAT) provided by Atlan.
- Replace `<namespace>` with the namespace you need to install the chart into. The secret and the release must live in the same namespace, or the pod fails with `ImagePullBackOff`.

The downloaded `values.yaml` already references this secret under `imagePullSecrets`. If you use a different secret name, update that field in the file.

</TabItem>
<TabItem value="private-registry" label="Private image repo">

Mirror the Atlan image to your enterprise registry and update `values.yaml` to point at it.

1. Authenticate with Docker Hub using the PAT from Atlan, then pull the source image. The image and tag come from `image.repository` and `image.tag` in the downloaded `values.yaml`:

 ```bash
 docker login -u atlanhq
 # When prompted for password, enter the PAT provided by Atlan
 docker pull <image.repository>:<image.tag>
 ```

2. Push the image to your enterprise's registry. Note down the new repository name and image tag.

3. Update `image.repository` and `image.tag` in `values.yaml` with the new values.

4. If your private registry requires authentication, create an image-pull secret in the target namespace and set `imagePullSecrets` in `values.yaml` to its name.

</TabItem>
</Tabs>

<h2 id="deploy-app">Deploy app</h2>

Follow these steps to deploy the secure app:

* Install the helm chart. The chart directory now carries your edited `values.yaml`, so no `-f` flag is needed:

 ```bash
 helm install {{deploymentValues.helmChartName}}-release ./{{deploymentValues.helmChartName}} -n <namespace>
 ```

 - Replace `<namespace>` with your target Kubernetes namespace.
 - The helm chart name `{{deploymentValues.helmChartName}}` is automatically used from your selected app.

The deployment process typically takes a few minutes to complete depending on factors like Kubernetes cluster resource availability, private image repository download time etc.

<h2 id="verify-app">Verify app</h2>

Follow these steps to verify deployment:

### Verify deployment status on cluster

1. Check pod status:

 ```bash
 kubectl get pods -n <namespace>
 ```

 The output appears similar to:

 ```
 NAME READY STATUS RESTARTS AGE
 <helm-chart-name>-release-<helm-chart-name>-5dff95cd85-cvk5z 1/1 Running 0 2m
 ```
 
 Replace `<helm-chart-name>` with your app's helm chart name (shown in the prerequisites section earlier in this guide).

 The pod status shows `Running` with `1/1` ready containers.

2. Verify logs for the running pod
 
 ```bash
 kubectl logs -n <namespace> -l app.kubernetes.io/name={{deploymentValues.helmChartName}} --tail=50 -f
 ```
 **Example application logs**: Look for these key log messages that confirm successful deployment:

 * `Uvicorn running on http://0.0.0.0:8000` - Web server started
 * `Workflow engine initialized` - Workflow processing ready
 * `dapr initialized. Status: Running` - Dapr runtime active
 * `Starting worker with task queue: atlan-<package-name>-DEPLOYMENT_NAME` - Worker process started (replace `<package-name>` with your app's package name)
 * `GET /server/ready 200` - Health check endpoint responding

### Verify registration via Atlan UI

Once the App is successfully deployed, it communicates to the Atlan tenant and registers itself. Verify App registration is successful in Atlan:

1. In the same Atlan tenant, navigate to **Workflows** > **Agent**.
2. Look for an entry named `<app_name>-<deployment_name>`, where `<app_name>` matches your selected app (for example, "Oracle" or "Microsoft SQL Server") and `<deployment_name>` is the deployment name you entered when generating the config.
3. Confirm the agent status displays as **Active**.

Agent registration and status takes a couple of minutes to reflect in the Atlan UI.

<h2 id="next-steps">Next steps</h2>

* [Configure workflow execution](https://docs.atlan.com/product/connections/self-deployed-runtime/how-tos/configure-workflow-execution): Set up workflow execution with secret retrieval for your Self-deployed Runtime

---

## Install on Kubernetes - Oracle

URL: https://docs.atlan.com/product/connections/self-deployed-runtime/how-tos/install-on-kubernetes
**Connector:** Oracle (database)

> Install an App on Kubernetes using Helm charts, Docker images, and specific configuration

:::info **Did you know?** 
SDR requires additional enablement and licensing. Contact your Atlan representative for details.
:::

:::warning Use the guided install wizard instead
**New Self-Deployed Runtime setups are encouraged to use the [guided install wizard](https://docs.atlan.com/product/connections/self-deployed-runtime/how-tos/install-guided).** It assembles a complete guide tailored to your lifecycle mode, platform, and image procurement on a single page—and it's where new setup options (for example, HTTP proxy and custom CA trust) are documented going forward.

This page is kept for existing users who already reference it and may not include the latest steps.
:::

<h2 id="prerequisites">Prerequisites</h2>

Before you begin, make sure you have:

* `kubectl` installed and configured with administrative access to your target Kubernetes cluster
* Helm version 3.0 or later installed on your deployment machine
* A [Docker Hub Personal Access Token (PAT)](https://start.1password.com/open/i?a=WAVUZSKJO5GMNMVBYWAWECXIUE&v=ouvp3xf5334cxoamyiipzjlewy&i=p76avgzmkkcbftldcuvr5jcof4&h=atlanhq.1password.com) from Atlan
* App-specific helm chart name: `{{deploymentValues.helmChartName}}` 
* Object storage: AWS S3, Google Cloud Storage, or Azure Blob Storage with read/write permissions
* Secret store access: AWS Secret Manager, Azure Key Vault, GCP Secret Manager, HashiCorp Vault, or Kubernetes Secrets with read permissions

:::warning For security reasons, the Docker Hub PAT Token is regenerated on a periodic basis. 
In case the token is embedded in automation scripts or CI/CD pipelines, those jobs may fail. 
Contact your Atlan representative for the latest token.
:::

<h2 id="download-required-files">Download required files</h2>

<h3 id="download-helm-chart">Download Helm chart</h3>

Download the Helm chart for the app:

```bash
helm pull oci://registry-1.docker.io/atlanhq/{{deploymentValues.helmChartName}} --untar
```

This unpacks the chart's `Chart.yaml`, `templates/`, and a default `values.yaml` into `./{{deploymentValues.helmChartName}}/`. You'll replace this default `values.yaml` with your Marketplace copy in the next step.

<h3 id="download-values-yaml">Download values.yaml</h3>

Atlan generates the helm `values.yaml` for your runtime directly from the Marketplace UI, including the OAuth client credentials your runtime uses to authenticate to your tenant.

1. Sign in to your Atlan tenant as an administrator, open **Connector** > **Marketplace**, select the app you want to deploy, and click **Download config for Self-Deployed Runtime** in the right-hand sidebar.

2. In the dialog, keep **New deployment** selected (this mints the OAuth client and full config for a fresh runtime), choose **Kubernetes (Helm)** as the deployment target, and enter a **Deployment name**: a short identifier (lowercase letters, digits, and dashes) that identifies this runtime; the agent in **Workflows > Agent** is named `<app_name>-<deployment_name>`.

3. Click **Generate**. Atlan mints a dedicated OAuth client and produces a `values.yaml` file with:
 - `global.atlanBaseUrl`, `global.clientId`, and `global.clientSecret` already filled in.
 - `image.repository`, `image.tag`, and `name` pinned to the active version for your tenant.
 - `objectstore` and `secretstore` placeholders for you to configure below.

<h3 id="replace-chart-values">Replace chart values.yaml</h3>

Replace the default `values.yaml` inside the unpacked chart with the `values.yaml` you downloaded from the Marketplace.

From this point on, all edits to `values.yaml` must be made inside `./{{deploymentValues.helmChartName}}/`.

<h2 id="modify-values-yaml">Modify values.yaml</h2>

### Object storage

Self-Deployed Runtime needs a store for reading or writing files. Configure the object storage that matches your environment:

:::tip Don't see your preferred object store?
If your preferred object store isn't listed here, [reach out to Atlan support](https://docs.atlan.com/support/submit-request). Support for additional object stores may be available.
:::

<Tabs>
<TabItem value="aws-s3" label="AWS S3" default>

**Required permissions:**

Apply object-level actions to `arn:aws:s3:::BUCKET/*` and the list action to `arn:aws:s3:::BUCKET` in separate IAM statement entries.

| IAM action | Operations covered |
|---|---|
| `s3:GetObject` | GetObject (full and byte-range), HeadObject |
| `s3:PutObject` | PutObject, CreateMultipartUpload, UploadPart, CompleteMultipartUpload |
| `s3:AbortMultipartUpload` | Abort in-flight multipart upload on error (required for streaming write error paths) |
| `s3:DeleteObject` | DeleteObject and DeleteObjects (bulk batch—same IAM action) |
| `s3:ListBucket` | ListObjectsV2—bucket-level permission, not object-level |

```json
{
 "Version": "2012-10-17",
 "Statement": [
 {
 "Effect": "Allow",
 "Action": [
 "s3:GetObject",
 "s3:PutObject",
 "s3:AbortMultipartUpload",
 "s3:DeleteObject"
 ],
 "Resource": "arn:aws:s3:::YOUR-BUCKET/*"
 },
 {
 "Effect": "Allow",
 "Action": "s3:ListBucket",
 "Resource": "arn:aws:s3:::YOUR-BUCKET"
 }
 ]
}
```

**AssumeRole**: when using `assumeRoleArn`, the caller identity additionally needs `sts:AssumeRole` on the target role ARN. The role itself holds the bucket policy described earlier.

**Configure:**

 1. Locate the `objectstore` attribute in `values.yaml`.
 2. Add AWS S3 configuration. For more information, see [AWS S3 Binding Spec](https://docs.dapr.io/reference/components-reference/supported-bindings/s3/).

 ```yaml
 objectstore:
 enabled: true
 spec:
 type: bindings.aws.s3
 version: v1
 metadata:
 - name: accessKey #optional, leave this empty for iam authentication
 value: ""
 - name: secretKey #optional, leave this empty for iam authentication
 value: ""
 - name: bucket #required, name of the bucket where application can write
 value: "<bucket-name>"
 - name: region #required, region of the bucket where application can write
 value: "<bucket-region>"
 - name: forcePathStyle
 value: "true"
 ```

</TabItem>
<TabItem value="gcp-storage" label="Google Cloud Storage">

**Required permissions:**

| IAM permission | Operations covered |
|---|---|
| `storage.objects.get` | GetObject (full and byte-range), object metadata / HeadObject equivalent |
| `storage.objects.create` | PutObject, resumable / streaming write |
| `storage.objects.delete` | DeleteObject (GCS has no native bulk-delete API—`delete_prefix` issues parallel single-object deletes) |
| `storage.objects.list` | ListObjects |

No `storage.buckets.*` permissions are needed. The smallest predefined role that covers all four is **`roles/storage.objectAdmin`** scoped to the bucket. Alternatively, create a custom role with exactly these four permissions.

**Configure:**

 1. Locate the `objectstore` attribute in `values.yaml`.
 2. Add Google Cloud Storage configuration. For more information, see [GCP Storage Bucket binding spec](https://docs.dapr.io/reference/components-reference/supported-bindings/gcpbucket/)

 ```yaml
 objectstore:
 enabled: true
 spec:
 type: bindings.gcp.bucket
 version: v1
 metadata:
 - name: bucket
 value: "your-gcs-bucket-name"
 - name: type
 value: "service_account"
 - name: project_id
 value: "your-gcp-project-id"
 ```

</TabItem>
<TabItem value="azure-blob" label="Azure Blob Storage">

**Required permissions:**

**RBAC**—assign at container or storage-account scope:

| RBAC action | Operations covered |
|---|---|
| `Microsoft.Storage/storageAccounts/blobServices/containers/blobs/read` | GetBlob, GetBlobProperties (HEAD), ListBlobs, byte-range GET |
| `Microsoft.Storage/storageAccounts/blobServices/containers/blobs/write` | PutBlob, PutBlock + PutBlockList (streaming / block write) |
| `Microsoft.Storage/storageAccounts/blobServices/containers/blobs/delete` | DeleteBlob, BlobBatch delete (bulk—up to 256 keys per request) |

The smallest predefined role covering all three is **`Storage Blob Data Contributor`**. `Storage Blob Data Owner` is a superset and is only needed if you additionally require POSIX ACL management on ADLS Gen2.

**SAS token**—minimum permissions at container scope: `r` (read) + `w` (write) + `d` (delete) + `l` (list), that is a container-scoped SAS with **`rwdl`**.

**ADLS Gen2 with POSIX ACLs**: if the storage account has hierarchical namespace enabled and you use ACL-based access control instead of RBAC, the principal needs Execute (`X`) on every parent directory and Read / Write / Delete on the objects in scope. RBAC (`Storage Blob Data Contributor`) is simpler and is recommended unless you have a specific ACL requirement.

**Configure:**

 1. Locate the `objectstore` attribute in `values.yaml`.
 2. Add Azure Blob Storage configuration. For more information, see [Azure Blob Storage binding spec](https://docs.dapr.io/reference/components-reference/supported-bindings/blobstorage/)

 ```yaml
 objectstore:
 enabled: true
 spec:
 type: bindings.azure.blobstorage
 version: v1
 metadata:
 - name: accountName
 value: "your-storage-account-name"
 - name: accountKey
 value: "your-storage-account-key"
 - name: containerName
 value: "your-container-name"
 ```

</TabItem>
</Tabs>

### Secret storage

Self-Deployed Runtime fetches secrets from a secret store to connect to the source systems. The secret store references are used to configure the workflow. Configure the secret store that aligns with your security infrastructure:

:::info Did you know?
Dapr supports additional secret stores which aren't mentioned here. For more information, see [Dapr secret store documentation](https://docs.dapr.io/reference/components-reference/supported-secret-stores/) for other configurations.
:::

:::warning Secret content format and naming
When storing credentials, follow the [secret naming and format requirements](https://docs.atlan.com/product/connections/self-deployed-runtime/how-tos/configure-workflow-execution#secret-content-format).
:::

<Tabs>
<TabItem value="aws-secret-manager" label="AWS Secret Manager" default>
 
 1. Locate the `secretstore` attribute in `values.yaml`.
 2. Add AWS Secret Manager configuration. For more information, see [AWS Secrets Manager](https://docs.dapr.io/reference/components-reference/supported-secret-stores/aws-secret-manager/)

 ```yaml
 secretstore:
 enabled: true
 spec:
 type: secretstores.aws.secretmanager
 version: v1
 metadata:
 - name: region # required, region in which secret is hosted
 value: <secret-region>
 # Needed if IAM authentication is not used
 - name: accessKey
 value: ""
 - name: secretKey
 value: ""
 ```

If you are using IAM role / IRSA authentication, leave `accessKey` and `secretKey` empty.

If you are using an IAM user instead, set:
- `accessKey` to the IAM user's access key ID
- `secretKey` to the IAM user's secret access key

That IAM user must have permission to read the target secret from AWS Secrets Manager:

```json
{
 "Version": "2012-10-17",
 "Statement": [
 {
 "Effect": "Allow",
 "Action": [
 "secretsmanager:GetSecretValue",
 "secretsmanager:DescribeSecret"
 ],
 "Resource": "arn:aws:secretsmanager:<region>:<account-id>:secret:<secret-name>*"
 }
 ]
}
```

:::note
Include the trailing `*` in the secret ARN. AWS appends a random suffix to secret names in the ARN, so omitting it can cause access failures.
:::

</TabItem>
<TabItem value="azure-key-vault" label="Azure Key Vault">

 1. Locate the `secretstore` attribute in `values.yaml`.
 2. Add Azure Key Vault configuration. For more information, see [Azure Key Vault secret store](https://docs.dapr.io/reference/components-reference/supported-secret-stores/azure-keyvault/)

 ```yaml
 secretstore:
 enabled: true
 spec:
 type: secretstores.azure.keyvault
 version: v1
 metadata:
 - name: vaultName
 value: "<your-keyvault-name>"
 - name: azureTenantId
 value: "<your-tenant-id>"
 - name: azureClientId
 value: "<your-client-id>"
 - name: azureClientSecret
 value: "<your-client-secret>"
 - name: azureEnvironment
 value: "AZUREPUBLICCLOUD" # Optional: AZUREPUBLICCLOUD, AZURECHINACLOUD, AZUREUSGOVERNMENTCLOUD, AZUREGERMANCLOUD
 ```
 Azure Key Vault supports multiple authentication methods:
 - **Client Secret**: Use `azureClientSecret` with tenant ID and client ID
 - **Certificate**: Use `azureCertificateFile` instead of client secret
 - **Managed Identity**: Omit authentication fields and use Azure managed identity

 For detailed authentication setup, see the [Authenticating to Azure](https://docs.dapr.io/developing-applications/integrations/azure/azure-authentication/authenticating-azure/) documentation.

</TabItem>
<TabItem value="gcp-secret-manager" label="GCP Secret Manager">

1. Locate the `secretstore` attribute in `values.yaml`.
2. Add Google Cloud Secret Manager configuration. For more information, see [GCP Secret Manager](https://docs.dapr.io/reference/components-reference/supported-secret-stores/gcp-secret-manager/)

 The GCP service account used in this configuration must have the `Secret Manager Secret Accessor` role (`roles/secretmanager.secretAccessor`) on the project where your secrets are stored. The metadata values below come from the service account's JSON key file.

 ```yaml
 secretstore:
 enabled: true
 spec:
 type: secretstores.gcp.secretmanager
 version: v1
 metadata:
 - name: type
 value: "service_account"
 - name: project_id
 value: "<project-id>"
 - name: private_key_id
 value: "<private-key-id>"
 - name: private_key
 value: "<private-key>"
 - name: client_email
 value: "<client-email>"
 - name: client_id
 value: "<client-id>"
 - name: auth_uri
 value: "https://accounts.google.com/o/oauth2/auth"
 - name: token_uri
 value: "https://oauth2.googleapis.com/token"
 - name: auth_provider_x509_cert_url
 value: "https://www.googleapis.com/oauth2/v1/certs"
 - name: client_x509_cert_url
 value: "https://www.googleapis.com/robot/v1/metadata/x509/<client-email>"
 ```

</TabItem>
<TabItem value="hashicorp-vault" label="HashiCorp Vault">

1. Locate the `secretstore` attribute in `values.yaml`.
2. Add HashiCorp Vault configuration. For more information, see [HashiCorp Vault](https://docs.dapr.io/reference/components-reference/supported-secret-stores/hashicorp-vault/)

 ```yaml
 secretstore:
 enabled: true
 spec:
 type: secretstores.hashicorp.vault
 version: v1
 metadata:
 - name: vaultAddr
 value: "[vault_address]" # Optional. Default: "https://127.0.0.1:8200"
 - name: caCert # Optional. This or caPath or caPem
 value: "[ca_cert]"
 - name: caPath # Optional. This or CaCert or caPem
 value: "[path_to_ca_cert_file]"
 - name: caPem # Optional. This or CaCert or CaPath
 value: "[encoded_ca_cert_pem]"
 - name: skipVerify # Optional. Default: false
 value: "[skip_tls_verification]"
 - name: tlsServerName # Optional.
 value: "[tls_config_server_name]"
 - name: vaultTokenMountPath # Required if vaultToken not provided. Path to token file.
 value: "[path_to_file_containing_token]"
 - name: vaultToken # Required if vaultTokenMountPath not provided. Token value.
 value: "[vault_token]"
 - name: vaultKVPrefix # Optional. Default: "dapr"
 value: "[vault_prefix]"
 - name: vaultKVUsePrefix # Optional. default: "true"
 value: "[true/false]"
 - name: enginePath # Optional. default: "secret"
 value: "secret"
 - name: vaultValueType # Optional. default: "map"
 value: "map"
 ```

</TabItem>
<TabItem value="kubernetes-secrets" label="Kubernetes Secrets">

1. Locate the `secretstore` attribute in `values.yaml`.
2. Add Kubernetes native secret storage. For more information, see [Kubernetes secrets](https://docs.dapr.io/reference/components-reference/supported-secret-stores/kubernetes-secret-store/)

 ```yaml
 secretstore:
 enabled: true
 spec:
 type: secretstores.kubernetes
 version: v1
 metadata:
 - name: defaultNamespace
 value: "default" # Optional: Default namespace to retrieve secrets from
 - name: kubeconfigPath
 value: "/path/to/kubeconfig" # Optional: Path to kubeconfig file
 ```
 When Dapr is deployed to a Kubernetes cluster, a secret store with the name `kubernetes` is automatically provisioned. You can use this native Kubernetes secret store with no need to create, deploy or maintain a component configuration file.

</TabItem>
<TabItem value="environment-variable-based" label="Environment Variables">

1. Locate the `secretstore` attribute in `values.yaml`.
2. Add Local environment variables as the spec. For more information, see [Local Environment Variables](https://docs.dapr.io/reference/components-reference/supported-secret-stores/envvar-secret-store/)

 ```yaml
 secretstore:
 enabled: true
 spec:
 type: secretstores.local.env
 version: v1
 ```

</TabItem>
</Tabs>

### Image source

Choose how the cluster pulls the app image. Most installs use Atlan's Docker Hub directly; mirror to a private registry if your organization requires it.

<Tabs>
<TabItem value="docker-hub" label="Public Docker Hub" default>

The chart pulls the app image from Atlan's Docker Hub at runtime. The pod needs a Kubernetes secret containing your Docker Hub PAT to authenticate:

```bash
kubectl create secret docker-registry atlan-docker-secret \
 --docker-server=docker.io \
 --docker-username=YOUR_USERNAME \
 --docker-password=YOUR_PAT_TOKEN \
 -n <namespace>
```

- Replace `YOUR_USERNAME` with the Docker Hub username provided by Atlan.
- Replace `YOUR_PAT_TOKEN` with the Personal Access Token (PAT) provided by Atlan.
- Replace `<namespace>` with the namespace you need to install the chart into. The secret and the release must live in the same namespace, or the pod fails with `ImagePullBackOff`.

The downloaded `values.yaml` already references this secret under `imagePullSecrets`. If you use a different secret name, update that field in the file.

</TabItem>
<TabItem value="private-registry" label="Private image repo">

Mirror the Atlan image to your enterprise registry and update `values.yaml` to point at it.

1. Authenticate with Docker Hub using the PAT from Atlan, then pull the source image. The image and tag come from `image.repository` and `image.tag` in the downloaded `values.yaml`:

 ```bash
 docker login -u atlanhq
 # When prompted for password, enter the PAT provided by Atlan
 docker pull <image.repository>:<image.tag>
 ```

2. Push the image to your enterprise's registry. Note down the new repository name and image tag.

3. Update `image.repository` and `image.tag` in `values.yaml` with the new values.

4. If your private registry requires authentication, create an image-pull secret in the target namespace and set `imagePullSecrets` in `values.yaml` to its name.

</TabItem>
</Tabs>

<h2 id="deploy-app">Deploy app</h2>

Follow these steps to deploy the secure app:

* Install the helm chart. The chart directory now carries your edited `values.yaml`, so no `-f` flag is needed:

 ```bash
 helm install {{deploymentValues.helmChartName}}-release ./{{deploymentValues.helmChartName}} -n <namespace>
 ```

 - Replace `<namespace>` with your target Kubernetes namespace.
 - The helm chart name `{{deploymentValues.helmChartName}}` is automatically used from your selected app.

The deployment process typically takes a few minutes to complete depending on factors like Kubernetes cluster resource availability, private image repository download time etc.

<h2 id="verify-app">Verify app</h2>

Follow these steps to verify deployment:

### Verify deployment status on cluster

1. Check pod status:

 ```bash
 kubectl get pods -n <namespace>
 ```

 The output appears similar to:

 ```
 NAME READY STATUS RESTARTS AGE
 <helm-chart-name>-release-<helm-chart-name>-5dff95cd85-cvk5z 1/1 Running 0 2m
 ```
 
 Replace `<helm-chart-name>` with your app's helm chart name (shown in the prerequisites section earlier in this guide).

 The pod status shows `Running` with `1/1` ready containers.

2. Verify logs for the running pod
 
 ```bash
 kubectl logs -n <namespace> -l app.kubernetes.io/name={{deploymentValues.helmChartName}} --tail=50 -f
 ```
 **Example application logs**: Look for these key log messages that confirm successful deployment:

 * `Uvicorn running on http://0.0.0.0:8000` - Web server started
 * `Workflow engine initialized` - Workflow processing ready
 * `dapr initialized. Status: Running` - Dapr runtime active
 * `Starting worker with task queue: atlan-<package-name>-DEPLOYMENT_NAME` - Worker process started (replace `<package-name>` with your app's package name)
 * `GET /server/ready 200` - Health check endpoint responding

### Verify registration via Atlan UI

Once the App is successfully deployed, it communicates to the Atlan tenant and registers itself. Verify App registration is successful in Atlan:

1. In the same Atlan tenant, navigate to **Workflows** > **Agent**.
2. Look for an entry named `<app_name>-<deployment_name>`, where `<app_name>` matches your selected app (for example, "Oracle" or "Microsoft SQL Server") and `<deployment_name>` is the deployment name you entered when generating the config.
3. Confirm the agent status displays as **Active**.

Agent registration and status takes a couple of minutes to reflect in the Atlan UI.

<h2 id="next-steps">Next steps</h2>

* [Configure workflow execution](https://docs.atlan.com/product/connections/self-deployed-runtime/how-tos/configure-workflow-execution): Set up workflow execution with secret retrieval for your Self-deployed Runtime

---

## Install on Kubernetes - PostgreSQL

URL: https://docs.atlan.com/product/connections/self-deployed-runtime/how-tos/install-on-kubernetes
**Connector:** PostgreSQL (database)

> Install an App on Kubernetes using Helm charts, Docker images, and specific configuration

:::info **Did you know?** 
SDR requires additional enablement and licensing. Contact your Atlan representative for details.
:::

:::warning Use the guided install wizard instead
**New Self-Deployed Runtime setups are encouraged to use the [guided install wizard](https://docs.atlan.com/product/connections/self-deployed-runtime/how-tos/install-guided).** It assembles a complete guide tailored to your lifecycle mode, platform, and image procurement on a single page—and it's where new setup options (for example, HTTP proxy and custom CA trust) are documented going forward.

This page is kept for existing users who already reference it and may not include the latest steps.
:::

<h2 id="prerequisites">Prerequisites</h2>

Before you begin, make sure you have:

* `kubectl` installed and configured with administrative access to your target Kubernetes cluster
* Helm version 3.0 or later installed on your deployment machine
* A [Docker Hub Personal Access Token (PAT)](https://start.1password.com/open/i?a=WAVUZSKJO5GMNMVBYWAWECXIUE&v=ouvp3xf5334cxoamyiipzjlewy&i=p76avgzmkkcbftldcuvr5jcof4&h=atlanhq.1password.com) from Atlan
* App-specific helm chart name: `{{deploymentValues.helmChartName}}` 
* Object storage: AWS S3, Google Cloud Storage, or Azure Blob Storage with read/write permissions
* Secret store access: AWS Secret Manager, Azure Key Vault, GCP Secret Manager, HashiCorp Vault, or Kubernetes Secrets with read permissions

:::warning For security reasons, the Docker Hub PAT Token is regenerated on a periodic basis. 
In case the token is embedded in automation scripts or CI/CD pipelines, those jobs may fail. 
Contact your Atlan representative for the latest token.
:::

<h2 id="download-required-files">Download required files</h2>

<h3 id="download-helm-chart">Download Helm chart</h3>

Download the Helm chart for the app:

```bash
helm pull oci://registry-1.docker.io/atlanhq/{{deploymentValues.helmChartName}} --untar
```

This unpacks the chart's `Chart.yaml`, `templates/`, and a default `values.yaml` into `./{{deploymentValues.helmChartName}}/`. You'll replace this default `values.yaml` with your Marketplace copy in the next step.

<h3 id="download-values-yaml">Download values.yaml</h3>

Atlan generates the helm `values.yaml` for your runtime directly from the Marketplace UI, including the OAuth client credentials your runtime uses to authenticate to your tenant.

1. Sign in to your Atlan tenant as an administrator, open **Connector** > **Marketplace**, select the app you want to deploy, and click **Download config for Self-Deployed Runtime** in the right-hand sidebar.

2. In the dialog, keep **New deployment** selected (this mints the OAuth client and full config for a fresh runtime), choose **Kubernetes (Helm)** as the deployment target, and enter a **Deployment name**: a short identifier (lowercase letters, digits, and dashes) that identifies this runtime; the agent in **Workflows > Agent** is named `<app_name>-<deployment_name>`.

3. Click **Generate**. Atlan mints a dedicated OAuth client and produces a `values.yaml` file with:
 - `global.atlanBaseUrl`, `global.clientId`, and `global.clientSecret` already filled in.
 - `image.repository`, `image.tag`, and `name` pinned to the active version for your tenant.
 - `objectstore` and `secretstore` placeholders for you to configure below.

<h3 id="replace-chart-values">Replace chart values.yaml</h3>

Replace the default `values.yaml` inside the unpacked chart with the `values.yaml` you downloaded from the Marketplace.

From this point on, all edits to `values.yaml` must be made inside `./{{deploymentValues.helmChartName}}/`.

<h2 id="modify-values-yaml">Modify values.yaml</h2>

### Object storage

Self-Deployed Runtime needs a store for reading or writing files. Configure the object storage that matches your environment:

:::tip Don't see your preferred object store?
If your preferred object store isn't listed here, [reach out to Atlan support](https://docs.atlan.com/support/submit-request). Support for additional object stores may be available.
:::

<Tabs>
<TabItem value="aws-s3" label="AWS S3" default>

**Required permissions:**

Apply object-level actions to `arn:aws:s3:::BUCKET/*` and the list action to `arn:aws:s3:::BUCKET` in separate IAM statement entries.

| IAM action | Operations covered |
|---|---|
| `s3:GetObject` | GetObject (full and byte-range), HeadObject |
| `s3:PutObject` | PutObject, CreateMultipartUpload, UploadPart, CompleteMultipartUpload |
| `s3:AbortMultipartUpload` | Abort in-flight multipart upload on error (required for streaming write error paths) |
| `s3:DeleteObject` | DeleteObject and DeleteObjects (bulk batch—same IAM action) |
| `s3:ListBucket` | ListObjectsV2—bucket-level permission, not object-level |

```json
{
 "Version": "2012-10-17",
 "Statement": [
 {
 "Effect": "Allow",
 "Action": [
 "s3:GetObject",
 "s3:PutObject",
 "s3:AbortMultipartUpload",
 "s3:DeleteObject"
 ],
 "Resource": "arn:aws:s3:::YOUR-BUCKET/*"
 },
 {
 "Effect": "Allow",
 "Action": "s3:ListBucket",
 "Resource": "arn:aws:s3:::YOUR-BUCKET"
 }
 ]
}
```

**AssumeRole**: when using `assumeRoleArn`, the caller identity additionally needs `sts:AssumeRole` on the target role ARN. The role itself holds the bucket policy described earlier.

**Configure:**

 1. Locate the `objectstore` attribute in `values.yaml`.
 2. Add AWS S3 configuration. For more information, see [AWS S3 Binding Spec](https://docs.dapr.io/reference/components-reference/supported-bindings/s3/).

 ```yaml
 objectstore:
 enabled: true
 spec:
 type: bindings.aws.s3
 version: v1
 metadata:
 - name: accessKey #optional, leave this empty for iam authentication
 value: ""
 - name: secretKey #optional, leave this empty for iam authentication
 value: ""
 - name: bucket #required, name of the bucket where application can write
 value: "<bucket-name>"
 - name: region #required, region of the bucket where application can write
 value: "<bucket-region>"
 - name: forcePathStyle
 value: "true"
 ```

</TabItem>
<TabItem value="gcp-storage" label="Google Cloud Storage">

**Required permissions:**

| IAM permission | Operations covered |
|---|---|
| `storage.objects.get` | GetObject (full and byte-range), object metadata / HeadObject equivalent |
| `storage.objects.create` | PutObject, resumable / streaming write |
| `storage.objects.delete` | DeleteObject (GCS has no native bulk-delete API—`delete_prefix` issues parallel single-object deletes) |
| `storage.objects.list` | ListObjects |

No `storage.buckets.*` permissions are needed. The smallest predefined role that covers all four is **`roles/storage.objectAdmin`** scoped to the bucket. Alternatively, create a custom role with exactly these four permissions.

**Configure:**

 1. Locate the `objectstore` attribute in `values.yaml`.
 2. Add Google Cloud Storage configuration. For more information, see [GCP Storage Bucket binding spec](https://docs.dapr.io/reference/components-reference/supported-bindings/gcpbucket/)

 ```yaml
 objectstore:
 enabled: true
 spec:
 type: bindings.gcp.bucket
 version: v1
 metadata:
 - name: bucket
 value: "your-gcs-bucket-name"
 - name: type
 value: "service_account"
 - name: project_id
 value: "your-gcp-project-id"
 ```

</TabItem>
<TabItem value="azure-blob" label="Azure Blob Storage">

**Required permissions:**

**RBAC**—assign at container or storage-account scope:

| RBAC action | Operations covered |
|---|---|
| `Microsoft.Storage/storageAccounts/blobServices/containers/blobs/read` | GetBlob, GetBlobProperties (HEAD), ListBlobs, byte-range GET |
| `Microsoft.Storage/storageAccounts/blobServices/containers/blobs/write` | PutBlob, PutBlock + PutBlockList (streaming / block write) |
| `Microsoft.Storage/storageAccounts/blobServices/containers/blobs/delete` | DeleteBlob, BlobBatch delete (bulk—up to 256 keys per request) |

The smallest predefined role covering all three is **`Storage Blob Data Contributor`**. `Storage Blob Data Owner` is a superset and is only needed if you additionally require POSIX ACL management on ADLS Gen2.

**SAS token**—minimum permissions at container scope: `r` (read) + `w` (write) + `d` (delete) + `l` (list), that is a container-scoped SAS with **`rwdl`**.

**ADLS Gen2 with POSIX ACLs**: if the storage account has hierarchical namespace enabled and you use ACL-based access control instead of RBAC, the principal needs Execute (`X`) on every parent directory and Read / Write / Delete on the objects in scope. RBAC (`Storage Blob Data Contributor`) is simpler and is recommended unless you have a specific ACL requirement.

**Configure:**

 1. Locate the `objectstore` attribute in `values.yaml`.
 2. Add Azure Blob Storage configuration. For more information, see [Azure Blob Storage binding spec](https://docs.dapr.io/reference/components-reference/supported-bindings/blobstorage/)

 ```yaml
 objectstore:
 enabled: true
 spec:
 type: bindings.azure.blobstorage
 version: v1
 metadata:
 - name: accountName
 value: "your-storage-account-name"
 - name: accountKey
 value: "your-storage-account-key"
 - name: containerName
 value: "your-container-name"
 ```

</TabItem>
</Tabs>

### Secret storage

Self-Deployed Runtime fetches secrets from a secret store to connect to the source systems. The secret store references are used to configure the workflow. Configure the secret store that aligns with your security infrastructure:

:::info Did you know?
Dapr supports additional secret stores which aren't mentioned here. For more information, see [Dapr secret store documentation](https://docs.dapr.io/reference/components-reference/supported-secret-stores/) for other configurations.
:::

:::warning Secret content format and naming
When storing credentials, follow the [secret naming and format requirements](https://docs.atlan.com/product/connections/self-deployed-runtime/how-tos/configure-workflow-execution#secret-content-format).
:::

<Tabs>
<TabItem value="aws-secret-manager" label="AWS Secret Manager" default>
 
 1. Locate the `secretstore` attribute in `values.yaml`.
 2. Add AWS Secret Manager configuration. For more information, see [AWS Secrets Manager](https://docs.dapr.io/reference/components-reference/supported-secret-stores/aws-secret-manager/)

 ```yaml
 secretstore:
 enabled: true
 spec:
 type: secretstores.aws.secretmanager
 version: v1
 metadata:
 - name: region # required, region in which secret is hosted
 value: <secret-region>
 # Needed if IAM authentication is not used
 - name: accessKey
 value: ""
 - name: secretKey
 value: ""
 ```

If you are using IAM role / IRSA authentication, leave `accessKey` and `secretKey` empty.

If you are using an IAM user instead, set:
- `accessKey` to the IAM user's access key ID
- `secretKey` to the IAM user's secret access key

That IAM user must have permission to read the target secret from AWS Secrets Manager:

```json
{
 "Version": "2012-10-17",
 "Statement": [
 {
 "Effect": "Allow",
 "Action": [
 "secretsmanager:GetSecretValue",
 "secretsmanager:DescribeSecret"
 ],
 "Resource": "arn:aws:secretsmanager:<region>:<account-id>:secret:<secret-name>*"
 }
 ]
}
```

:::note
Include the trailing `*` in the secret ARN. AWS appends a random suffix to secret names in the ARN, so omitting it can cause access failures.
:::

</TabItem>
<TabItem value="azure-key-vault" label="Azure Key Vault">

 1. Locate the `secretstore` attribute in `values.yaml`.
 2. Add Azure Key Vault configuration. For more information, see [Azure Key Vault secret store](https://docs.dapr.io/reference/components-reference/supported-secret-stores/azure-keyvault/)

 ```yaml
 secretstore:
 enabled: true
 spec:
 type: secretstores.azure.keyvault
 version: v1
 metadata:
 - name: vaultName
 value: "<your-keyvault-name>"
 - name: azureTenantId
 value: "<your-tenant-id>"
 - name: azureClientId
 value: "<your-client-id>"
 - name: azureClientSecret
 value: "<your-client-secret>"
 - name: azureEnvironment
 value: "AZUREPUBLICCLOUD" # Optional: AZUREPUBLICCLOUD, AZURECHINACLOUD, AZUREUSGOVERNMENTCLOUD, AZUREGERMANCLOUD
 ```
 Azure Key Vault supports multiple authentication methods:
 - **Client Secret**: Use `azureClientSecret` with tenant ID and client ID
 - **Certificate**: Use `azureCertificateFile` instead of client secret
 - **Managed Identity**: Omit authentication fields and use Azure managed identity

 For detailed authentication setup, see the [Authenticating to Azure](https://docs.dapr.io/developing-applications/integrations/azure/azure-authentication/authenticating-azure/) documentation.

</TabItem>
<TabItem value="gcp-secret-manager" label="GCP Secret Manager">

1. Locate the `secretstore` attribute in `values.yaml`.
2. Add Google Cloud Secret Manager configuration. For more information, see [GCP Secret Manager](https://docs.dapr.io/reference/components-reference/supported-secret-stores/gcp-secret-manager/)

 The GCP service account used in this configuration must have the `Secret Manager Secret Accessor` role (`roles/secretmanager.secretAccessor`) on the project where your secrets are stored. The metadata values below come from the service account's JSON key file.

 ```yaml
 secretstore:
 enabled: true
 spec:
 type: secretstores.gcp.secretmanager
 version: v1
 metadata:
 - name: type
 value: "service_account"
 - name: project_id
 value: "<project-id>"
 - name: private_key_id
 value: "<private-key-id>"
 - name: private_key
 value: "<private-key>"
 - name: client_email
 value: "<client-email>"
 - name: client_id
 value: "<client-id>"
 - name: auth_uri
 value: "https://accounts.google.com/o/oauth2/auth"
 - name: token_uri
 value: "https://oauth2.googleapis.com/token"
 - name: auth_provider_x509_cert_url
 value: "https://www.googleapis.com/oauth2/v1/certs"
 - name: client_x509_cert_url
 value: "https://www.googleapis.com/robot/v1/metadata/x509/<client-email>"
 ```

</TabItem>
<TabItem value="hashicorp-vault" label="HashiCorp Vault">

1. Locate the `secretstore` attribute in `values.yaml`.
2. Add HashiCorp Vault configuration. For more information, see [HashiCorp Vault](https://docs.dapr.io/reference/components-reference/supported-secret-stores/hashicorp-vault/)

 ```yaml
 secretstore:
 enabled: true
 spec:
 type: secretstores.hashicorp.vault
 version: v1
 metadata:
 - name: vaultAddr
 value: "[vault_address]" # Optional. Default: "https://127.0.0.1:8200"
 - name: caCert # Optional. This or caPath or caPem
 value: "[ca_cert]"
 - name: caPath # Optional. This or CaCert or caPem
 value: "[path_to_ca_cert_file]"
 - name: caPem # Optional. This or CaCert or CaPath
 value: "[encoded_ca_cert_pem]"
 - name: skipVerify # Optional. Default: false
 value: "[skip_tls_verification]"
 - name: tlsServerName # Optional.
 value: "[tls_config_server_name]"
 - name: vaultTokenMountPath # Required if vaultToken not provided. Path to token file.
 value: "[path_to_file_containing_token]"
 - name: vaultToken # Required if vaultTokenMountPath not provided. Token value.
 value: "[vault_token]"
 - name: vaultKVPrefix # Optional. Default: "dapr"
 value: "[vault_prefix]"
 - name: vaultKVUsePrefix # Optional. default: "true"
 value: "[true/false]"
 - name: enginePath # Optional. default: "secret"
 value: "secret"
 - name: vaultValueType # Optional. default: "map"
 value: "map"
 ```

</TabItem>
<TabItem value="kubernetes-secrets" label="Kubernetes Secrets">

1. Locate the `secretstore` attribute in `values.yaml`.
2. Add Kubernetes native secret storage. For more information, see [Kubernetes secrets](https://docs.dapr.io/reference/components-reference/supported-secret-stores/kubernetes-secret-store/)

 ```yaml
 secretstore:
 enabled: true
 spec:
 type: secretstores.kubernetes
 version: v1
 metadata:
 - name: defaultNamespace
 value: "default" # Optional: Default namespace to retrieve secrets from
 - name: kubeconfigPath
 value: "/path/to/kubeconfig" # Optional: Path to kubeconfig file
 ```
 When Dapr is deployed to a Kubernetes cluster, a secret store with the name `kubernetes` is automatically provisioned. You can use this native Kubernetes secret store with no need to create, deploy or maintain a component configuration file.

</TabItem>
<TabItem value="environment-variable-based" label="Environment Variables">

1. Locate the `secretstore` attribute in `values.yaml`.
2. Add Local environment variables as the spec. For more information, see [Local Environment Variables](https://docs.dapr.io/reference/components-reference/supported-secret-stores/envvar-secret-store/)

 ```yaml
 secretstore:
 enabled: true
 spec:
 type: secretstores.local.env
 version: v1
 ```

</TabItem>
</Tabs>

### Image source

Choose how the cluster pulls the app image. Most installs use Atlan's Docker Hub directly; mirror to a private registry if your organization requires it.

<Tabs>
<TabItem value="docker-hub" label="Public Docker Hub" default>

The chart pulls the app image from Atlan's Docker Hub at runtime. The pod needs a Kubernetes secret containing your Docker Hub PAT to authenticate:

```bash
kubectl create secret docker-registry atlan-docker-secret \
 --docker-server=docker.io \
 --docker-username=YOUR_USERNAME \
 --docker-password=YOUR_PAT_TOKEN \
 -n <namespace>
```

- Replace `YOUR_USERNAME` with the Docker Hub username provided by Atlan.
- Replace `YOUR_PAT_TOKEN` with the Personal Access Token (PAT) provided by Atlan.
- Replace `<namespace>` with the namespace you need to install the chart into. The secret and the release must live in the same namespace, or the pod fails with `ImagePullBackOff`.

The downloaded `values.yaml` already references this secret under `imagePullSecrets`. If you use a different secret name, update that field in the file.

</TabItem>
<TabItem value="private-registry" label="Private image repo">

Mirror the Atlan image to your enterprise registry and update `values.yaml` to point at it.

1. Authenticate with Docker Hub using the PAT from Atlan, then pull the source image. The image and tag come from `image.repository` and `image.tag` in the downloaded `values.yaml`:

 ```bash
 docker login -u atlanhq
 # When prompted for password, enter the PAT provided by Atlan
 docker pull <image.repository>:<image.tag>
 ```

2. Push the image to your enterprise's registry. Note down the new repository name and image tag.

3. Update `image.repository` and `image.tag` in `values.yaml` with the new values.

4. If your private registry requires authentication, create an image-pull secret in the target namespace and set `imagePullSecrets` in `values.yaml` to its name.

</TabItem>
</Tabs>

<h2 id="deploy-app">Deploy app</h2>

Follow these steps to deploy the secure app:

* Install the helm chart. The chart directory now carries your edited `values.yaml`, so no `-f` flag is needed:

 ```bash
 helm install {{deploymentValues.helmChartName}}-release ./{{deploymentValues.helmChartName}} -n <namespace>
 ```

 - Replace `<namespace>` with your target Kubernetes namespace.
 - The helm chart name `{{deploymentValues.helmChartName}}` is automatically used from your selected app.

The deployment process typically takes a few minutes to complete depending on factors like Kubernetes cluster resource availability, private image repository download time etc.

<h2 id="verify-app">Verify app</h2>

Follow these steps to verify deployment:

### Verify deployment status on cluster

1. Check pod status:

 ```bash
 kubectl get pods -n <namespace>
 ```

 The output appears similar to:

 ```
 NAME READY STATUS RESTARTS AGE
 <helm-chart-name>-release-<helm-chart-name>-5dff95cd85-cvk5z 1/1 Running 0 2m
 ```
 
 Replace `<helm-chart-name>` with your app's helm chart name (shown in the prerequisites section earlier in this guide).

 The pod status shows `Running` with `1/1` ready containers.

2. Verify logs for the running pod
 
 ```bash
 kubectl logs -n <namespace> -l app.kubernetes.io/name={{deploymentValues.helmChartName}} --tail=50 -f
 ```
 **Example application logs**: Look for these key log messages that confirm successful deployment:

 * `Uvicorn running on http://0.0.0.0:8000` - Web server started
 * `Workflow engine initialized` - Workflow processing ready
 * `dapr initialized. Status: Running` - Dapr runtime active
 * `Starting worker with task queue: atlan-<package-name>-DEPLOYMENT_NAME` - Worker process started (replace `<package-name>` with your app's package name)
 * `GET /server/ready 200` - Health check endpoint responding

### Verify registration via Atlan UI

Once the App is successfully deployed, it communicates to the Atlan tenant and registers itself. Verify App registration is successful in Atlan:

1. In the same Atlan tenant, navigate to **Workflows** > **Agent**.
2. Look for an entry named `<app_name>-<deployment_name>`, where `<app_name>` matches your selected app (for example, "Oracle" or "Microsoft SQL Server") and `<deployment_name>` is the deployment name you entered when generating the config.
3. Confirm the agent status displays as **Active**.

Agent registration and status takes a couple of minutes to reflect in the Atlan UI.

<h2 id="next-steps">Next steps</h2>

* [Configure workflow execution](https://docs.atlan.com/product/connections/self-deployed-runtime/how-tos/configure-workflow-execution): Set up workflow execution with secret retrieval for your Self-deployed Runtime

---

## Install on Kubernetes - SAP ASE

URL: https://docs.atlan.com/product/connections/self-deployed-runtime/how-tos/install-on-kubernetes
**Connector:** SAP ASE (database)

> Install an App on Kubernetes using Helm charts, Docker images, and specific configuration

:::info **Did you know?** 
SDR requires additional enablement and licensing. Contact your Atlan representative for details.
:::

:::warning Use the guided install wizard instead
**New Self-Deployed Runtime setups are encouraged to use the [guided install wizard](https://docs.atlan.com/product/connections/self-deployed-runtime/how-tos/install-guided).** It assembles a complete guide tailored to your lifecycle mode, platform, and image procurement on a single page—and it's where new setup options (for example, HTTP proxy and custom CA trust) are documented going forward.

This page is kept for existing users who already reference it and may not include the latest steps.
:::

<h2 id="prerequisites">Prerequisites</h2>

Before you begin, make sure you have:

* `kubectl` installed and configured with administrative access to your target Kubernetes cluster
* Helm version 3.0 or later installed on your deployment machine
* A [Docker Hub Personal Access Token (PAT)](https://start.1password.com/open/i?a=WAVUZSKJO5GMNMVBYWAWECXIUE&v=ouvp3xf5334cxoamyiipzjlewy&i=p76avgzmkkcbftldcuvr5jcof4&h=atlanhq.1password.com) from Atlan
* App-specific helm chart name: `{{deploymentValues.helmChartName}}` 
* Object storage: AWS S3, Google Cloud Storage, or Azure Blob Storage with read/write permissions
* Secret store access: AWS Secret Manager, Azure Key Vault, GCP Secret Manager, HashiCorp Vault, or Kubernetes Secrets with read permissions

:::warning For security reasons, the Docker Hub PAT Token is regenerated on a periodic basis. 
In case the token is embedded in automation scripts or CI/CD pipelines, those jobs may fail. 
Contact your Atlan representative for the latest token.
:::

<h2 id="download-required-files">Download required files</h2>

<h3 id="download-helm-chart">Download Helm chart</h3>

Download the Helm chart for the app:

```bash
helm pull oci://registry-1.docker.io/atlanhq/{{deploymentValues.helmChartName}} --untar
```

This unpacks the chart's `Chart.yaml`, `templates/`, and a default `values.yaml` into `./{{deploymentValues.helmChartName}}/`. You'll replace this default `values.yaml` with your Marketplace copy in the next step.

<h3 id="download-values-yaml">Download values.yaml</h3>

Atlan generates the helm `values.yaml` for your runtime directly from the Marketplace UI, including the OAuth client credentials your runtime uses to authenticate to your tenant.

1. Sign in to your Atlan tenant as an administrator, open **Connector** > **Marketplace**, select the app you want to deploy, and click **Download config for Self-Deployed Runtime** in the right-hand sidebar.

2. In the dialog, keep **New deployment** selected (this mints the OAuth client and full config for a fresh runtime), choose **Kubernetes (Helm)** as the deployment target, and enter a **Deployment name**: a short identifier (lowercase letters, digits, and dashes) that identifies this runtime; the agent in **Workflows > Agent** is named `<app_name>-<deployment_name>`.

3. Click **Generate**. Atlan mints a dedicated OAuth client and produces a `values.yaml` file with:
 - `global.atlanBaseUrl`, `global.clientId`, and `global.clientSecret` already filled in.
 - `image.repository`, `image.tag`, and `name` pinned to the active version for your tenant.
 - `objectstore` and `secretstore` placeholders for you to configure below.

<h3 id="replace-chart-values">Replace chart values.yaml</h3>

Replace the default `values.yaml` inside the unpacked chart with the `values.yaml` you downloaded from the Marketplace.

From this point on, all edits to `values.yaml` must be made inside `./{{deploymentValues.helmChartName}}/`.

<h2 id="modify-values-yaml">Modify values.yaml</h2>

### Object storage

Self-Deployed Runtime needs a store for reading or writing files. Configure the object storage that matches your environment:

:::tip Don't see your preferred object store?
If your preferred object store isn't listed here, [reach out to Atlan support](https://docs.atlan.com/support/submit-request). Support for additional object stores may be available.
:::

<Tabs>
<TabItem value="aws-s3" label="AWS S3" default>

**Required permissions:**

Apply object-level actions to `arn:aws:s3:::BUCKET/*` and the list action to `arn:aws:s3:::BUCKET` in separate IAM statement entries.

| IAM action | Operations covered |
|---|---|
| `s3:GetObject` | GetObject (full and byte-range), HeadObject |
| `s3:PutObject` | PutObject, CreateMultipartUpload, UploadPart, CompleteMultipartUpload |
| `s3:AbortMultipartUpload` | Abort in-flight multipart upload on error (required for streaming write error paths) |
| `s3:DeleteObject` | DeleteObject and DeleteObjects (bulk batch—same IAM action) |
| `s3:ListBucket` | ListObjectsV2—bucket-level permission, not object-level |

```json
{
 "Version": "2012-10-17",
 "Statement": [
 {
 "Effect": "Allow",
 "Action": [
 "s3:GetObject",
 "s3:PutObject",
 "s3:AbortMultipartUpload",
 "s3:DeleteObject"
 ],
 "Resource": "arn:aws:s3:::YOUR-BUCKET/*"
 },
 {
 "Effect": "Allow",
 "Action": "s3:ListBucket",
 "Resource": "arn:aws:s3:::YOUR-BUCKET"
 }
 ]
}
```

**AssumeRole**: when using `assumeRoleArn`, the caller identity additionally needs `sts:AssumeRole` on the target role ARN. The role itself holds the bucket policy described earlier.

**Configure:**

 1. Locate the `objectstore` attribute in `values.yaml`.
 2. Add AWS S3 configuration. For more information, see [AWS S3 Binding Spec](https://docs.dapr.io/reference/components-reference/supported-bindings/s3/).

 ```yaml
 objectstore:
 enabled: true
 spec:
 type: bindings.aws.s3
 version: v1
 metadata:
 - name: accessKey #optional, leave this empty for iam authentication
 value: ""
 - name: secretKey #optional, leave this empty for iam authentication
 value: ""
 - name: bucket #required, name of the bucket where application can write
 value: "<bucket-name>"
 - name: region #required, region of the bucket where application can write
 value: "<bucket-region>"
 - name: forcePathStyle
 value: "true"
 ```

</TabItem>
<TabItem value="gcp-storage" label="Google Cloud Storage">

**Required permissions:**

| IAM permission | Operations covered |
|---|---|
| `storage.objects.get` | GetObject (full and byte-range), object metadata / HeadObject equivalent |
| `storage.objects.create` | PutObject, resumable / streaming write |
| `storage.objects.delete` | DeleteObject (GCS has no native bulk-delete API—`delete_prefix` issues parallel single-object deletes) |
| `storage.objects.list` | ListObjects |

No `storage.buckets.*` permissions are needed. The smallest predefined role that covers all four is **`roles/storage.objectAdmin`** scoped to the bucket. Alternatively, create a custom role with exactly these four permissions.

**Configure:**

 1. Locate the `objectstore` attribute in `values.yaml`.
 2. Add Google Cloud Storage configuration. For more information, see [GCP Storage Bucket binding spec](https://docs.dapr.io/reference/components-reference/supported-bindings/gcpbucket/)

 ```yaml
 objectstore:
 enabled: true
 spec:
 type: bindings.gcp.bucket
 version: v1
 metadata:
 - name: bucket
 value: "your-gcs-bucket-name"
 - name: type
 value: "service_account"
 - name: project_id
 value: "your-gcp-project-id"
 ```

</TabItem>
<TabItem value="azure-blob" label="Azure Blob Storage">

**Required permissions:**

**RBAC**—assign at container or storage-account scope:

| RBAC action | Operations covered |
|---|---|
| `Microsoft.Storage/storageAccounts/blobServices/containers/blobs/read` | GetBlob, GetBlobProperties (HEAD), ListBlobs, byte-range GET |
| `Microsoft.Storage/storageAccounts/blobServices/containers/blobs/write` | PutBlob, PutBlock + PutBlockList (streaming / block write) |
| `Microsoft.Storage/storageAccounts/blobServices/containers/blobs/delete` | DeleteBlob, BlobBatch delete (bulk—up to 256 keys per request) |

The smallest predefined role covering all three is **`Storage Blob Data Contributor`**. `Storage Blob Data Owner` is a superset and is only needed if you additionally require POSIX ACL management on ADLS Gen2.

**SAS token**—minimum permissions at container scope: `r` (read) + `w` (write) + `d` (delete) + `l` (list), that is a container-scoped SAS with **`rwdl`**.

**ADLS Gen2 with POSIX ACLs**: if the storage account has hierarchical namespace enabled and you use ACL-based access control instead of RBAC, the principal needs Execute (`X`) on every parent directory and Read / Write / Delete on the objects in scope. RBAC (`Storage Blob Data Contributor`) is simpler and is recommended unless you have a specific ACL requirement.

**Configure:**

 1. Locate the `objectstore` attribute in `values.yaml`.
 2. Add Azure Blob Storage configuration. For more information, see [Azure Blob Storage binding spec](https://docs.dapr.io/reference/components-reference/supported-bindings/blobstorage/)

 ```yaml
 objectstore:
 enabled: true
 spec:
 type: bindings.azure.blobstorage
 version: v1
 metadata:
 - name: accountName
 value: "your-storage-account-name"
 - name: accountKey
 value: "your-storage-account-key"
 - name: containerName
 value: "your-container-name"
 ```

</TabItem>
</Tabs>

### Secret storage

Self-Deployed Runtime fetches secrets from a secret store to connect to the source systems. The secret store references are used to configure the workflow. Configure the secret store that aligns with your security infrastructure:

:::info Did you know?
Dapr supports additional secret stores which aren't mentioned here. For more information, see [Dapr secret store documentation](https://docs.dapr.io/reference/components-reference/supported-secret-stores/) for other configurations.
:::

:::warning Secret content format and naming
When storing credentials, follow the [secret naming and format requirements](https://docs.atlan.com/product/connections/self-deployed-runtime/how-tos/configure-workflow-execution#secret-content-format).
:::

<Tabs>
<TabItem value="aws-secret-manager" label="AWS Secret Manager" default>
 
 1. Locate the `secretstore` attribute in `values.yaml`.
 2. Add AWS Secret Manager configuration. For more information, see [AWS Secrets Manager](https://docs.dapr.io/reference/components-reference/supported-secret-stores/aws-secret-manager/)

 ```yaml
 secretstore:
 enabled: true
 spec:
 type: secretstores.aws.secretmanager
 version: v1
 metadata:
 - name: region # required, region in which secret is hosted
 value: <secret-region>
 # Needed if IAM authentication is not used
 - name: accessKey
 value: ""
 - name: secretKey
 value: ""
 ```

If you are using IAM role / IRSA authentication, leave `accessKey` and `secretKey` empty.

If you are using an IAM user instead, set:
- `accessKey` to the IAM user's access key ID
- `secretKey` to the IAM user's secret access key

That IAM user must have permission to read the target secret from AWS Secrets Manager:

```json
{
 "Version": "2012-10-17",
 "Statement": [
 {
 "Effect": "Allow",
 "Action": [
 "secretsmanager:GetSecretValue",
 "secretsmanager:DescribeSecret"
 ],
 "Resource": "arn:aws:secretsmanager:<region>:<account-id>:secret:<secret-name>*"
 }
 ]
}
```

:::note
Include the trailing `*` in the secret ARN. AWS appends a random suffix to secret names in the ARN, so omitting it can cause access failures.
:::

</TabItem>
<TabItem value="azure-key-vault" label="Azure Key Vault">

 1. Locate the `secretstore` attribute in `values.yaml`.
 2. Add Azure Key Vault configuration. For more information, see [Azure Key Vault secret store](https://docs.dapr.io/reference/components-reference/supported-secret-stores/azure-keyvault/)

 ```yaml
 secretstore:
 enabled: true
 spec:
 type: secretstores.azure.keyvault
 version: v1
 metadata:
 - name: vaultName
 value: "<your-keyvault-name>"
 - name: azureTenantId
 value: "<your-tenant-id>"
 - name: azureClientId
 value: "<your-client-id>"
 - name: azureClientSecret
 value: "<your-client-secret>"
 - name: azureEnvironment
 value: "AZUREPUBLICCLOUD" # Optional: AZUREPUBLICCLOUD, AZURECHINACLOUD, AZUREUSGOVERNMENTCLOUD, AZUREGERMANCLOUD
 ```
 Azure Key Vault supports multiple authentication methods:
 - **Client Secret**: Use `azureClientSecret` with tenant ID and client ID
 - **Certificate**: Use `azureCertificateFile` instead of client secret
 - **Managed Identity**: Omit authentication fields and use Azure managed identity

 For detailed authentication setup, see the [Authenticating to Azure](https://docs.dapr.io/developing-applications/integrations/azure/azure-authentication/authenticating-azure/) documentation.

</TabItem>
<TabItem value="gcp-secret-manager" label="GCP Secret Manager">

1. Locate the `secretstore` attribute in `values.yaml`.
2. Add Google Cloud Secret Manager configuration. For more information, see [GCP Secret Manager](https://docs.dapr.io/reference/components-reference/supported-secret-stores/gcp-secret-manager/)

 The GCP service account used in this configuration must have the `Secret Manager Secret Accessor` role (`roles/secretmanager.secretAccessor`) on the project where your secrets are stored. The metadata values below come from the service account's JSON key file.

 ```yaml
 secretstore:
 enabled: true
 spec:
 type: secretstores.gcp.secretmanager
 version: v1
 metadata:
 - name: type
 value: "service_account"
 - name: project_id
 value: "<project-id>"
 - name: private_key_id
 value: "<private-key-id>"
 - name: private_key
 value: "<private-key>"
 - name: client_email
 value: "<client-email>"
 - name: client_id
 value: "<client-id>"
 - name: auth_uri
 value: "https://accounts.google.com/o/oauth2/auth"
 - name: token_uri
 value: "https://oauth2.googleapis.com/token"
 - name: auth_provider_x509_cert_url
 value: "https://www.googleapis.com/oauth2/v1/certs"
 - name: client_x509_cert_url
 value: "https://www.googleapis.com/robot/v1/metadata/x509/<client-email>"
 ```

</TabItem>
<TabItem value="hashicorp-vault" label="HashiCorp Vault">

1. Locate the `secretstore` attribute in `values.yaml`.
2. Add HashiCorp Vault configuration. For more information, see [HashiCorp Vault](https://docs.dapr.io/reference/components-reference/supported-secret-stores/hashicorp-vault/)

 ```yaml
 secretstore:
 enabled: true
 spec:
 type: secretstores.hashicorp.vault
 version: v1
 metadata:
 - name: vaultAddr
 value: "[vault_address]" # Optional. Default: "https://127.0.0.1:8200"
 - name: caCert # Optional. This or caPath or caPem
 value: "[ca_cert]"
 - name: caPath # Optional. This or CaCert or caPem
 value: "[path_to_ca_cert_file]"
 - name: caPem # Optional. This or CaCert or CaPath
 value: "[encoded_ca_cert_pem]"
 - name: skipVerify # Optional. Default: false
 value: "[skip_tls_verification]"
 - name: tlsServerName # Optional.
 value: "[tls_config_server_name]"
 - name: vaultTokenMountPath # Required if vaultToken not provided. Path to token file.
 value: "[path_to_file_containing_token]"
 - name: vaultToken # Required if vaultTokenMountPath not provided. Token value.
 value: "[vault_token]"
 - name: vaultKVPrefix # Optional. Default: "dapr"
 value: "[vault_prefix]"
 - name: vaultKVUsePrefix # Optional. default: "true"
 value: "[true/false]"
 - name: enginePath # Optional. default: "secret"
 value: "secret"
 - name: vaultValueType # Optional. default: "map"
 value: "map"
 ```

</TabItem>
<TabItem value="kubernetes-secrets" label="Kubernetes Secrets">

1. Locate the `secretstore` attribute in `values.yaml`.
2. Add Kubernetes native secret storage. For more information, see [Kubernetes secrets](https://docs.dapr.io/reference/components-reference/supported-secret-stores/kubernetes-secret-store/)

 ```yaml
 secretstore:
 enabled: true
 spec:
 type: secretstores.kubernetes
 version: v1
 metadata:
 - name: defaultNamespace
 value: "default" # Optional: Default namespace to retrieve secrets from
 - name: kubeconfigPath
 value: "/path/to/kubeconfig" # Optional: Path to kubeconfig file
 ```
 When Dapr is deployed to a Kubernetes cluster, a secret store with the name `kubernetes` is automatically provisioned. You can use this native Kubernetes secret store with no need to create, deploy or maintain a component configuration file.

</TabItem>
<TabItem value="environment-variable-based" label="Environment Variables">

1. Locate the `secretstore` attribute in `values.yaml`.
2. Add Local environment variables as the spec. For more information, see [Local Environment Variables](https://docs.dapr.io/reference/components-reference/supported-secret-stores/envvar-secret-store/)

 ```yaml
 secretstore:
 enabled: true
 spec:
 type: secretstores.local.env
 version: v1
 ```

</TabItem>
</Tabs>

### Image source

Choose how the cluster pulls the app image. Most installs use Atlan's Docker Hub directly; mirror to a private registry if your organization requires it.

<Tabs>
<TabItem value="docker-hub" label="Public Docker Hub" default>

The chart pulls the app image from Atlan's Docker Hub at runtime. The pod needs a Kubernetes secret containing your Docker Hub PAT to authenticate:

```bash
kubectl create secret docker-registry atlan-docker-secret \
 --docker-server=docker.io \
 --docker-username=YOUR_USERNAME \
 --docker-password=YOUR_PAT_TOKEN \
 -n <namespace>
```

- Replace `YOUR_USERNAME` with the Docker Hub username provided by Atlan.
- Replace `YOUR_PAT_TOKEN` with the Personal Access Token (PAT) provided by Atlan.
- Replace `<namespace>` with the namespace you need to install the chart into. The secret and the release must live in the same namespace, or the pod fails with `ImagePullBackOff`.

The downloaded `values.yaml` already references this secret under `imagePullSecrets`. If you use a different secret name, update that field in the file.

</TabItem>
<TabItem value="private-registry" label="Private image repo">

Mirror the Atlan image to your enterprise registry and update `values.yaml` to point at it.

1. Authenticate with Docker Hub using the PAT from Atlan, then pull the source image. The image and tag come from `image.repository` and `image.tag` in the downloaded `values.yaml`:

 ```bash
 docker login -u atlanhq
 # When prompted for password, enter the PAT provided by Atlan
 docker pull <image.repository>:<image.tag>
 ```

2. Push the image to your enterprise's registry. Note down the new repository name and image tag.

3. Update `image.repository` and `image.tag` in `values.yaml` with the new values.

4. If your private registry requires authentication, create an image-pull secret in the target namespace and set `imagePullSecrets` in `values.yaml` to its name.

</TabItem>
</Tabs>

<h2 id="deploy-app">Deploy app</h2>

Follow these steps to deploy the secure app:

* Install the helm chart. The chart directory now carries your edited `values.yaml`, so no `-f` flag is needed:

 ```bash
 helm install {{deploymentValues.helmChartName}}-release ./{{deploymentValues.helmChartName}} -n <namespace>
 ```

 - Replace `<namespace>` with your target Kubernetes namespace.
 - The helm chart name `{{deploymentValues.helmChartName}}` is automatically used from your selected app.

The deployment process typically takes a few minutes to complete depending on factors like Kubernetes cluster resource availability, private image repository download time etc.

<h2 id="verify-app">Verify app</h2>

Follow these steps to verify deployment:

### Verify deployment status on cluster

1. Check pod status:

 ```bash
 kubectl get pods -n <namespace>
 ```

 The output appears similar to:

 ```
 NAME READY STATUS RESTARTS AGE
 <helm-chart-name>-release-<helm-chart-name>-5dff95cd85-cvk5z 1/1 Running 0 2m
 ```
 
 Replace `<helm-chart-name>` with your app's helm chart name (shown in the prerequisites section earlier in this guide).

 The pod status shows `Running` with `1/1` ready containers.

2. Verify logs for the running pod
 
 ```bash
 kubectl logs -n <namespace> -l app.kubernetes.io/name={{deploymentValues.helmChartName}} --tail=50 -f
 ```
 **Example application logs**: Look for these key log messages that confirm successful deployment:

 * `Uvicorn running on http://0.0.0.0:8000` - Web server started
 * `Workflow engine initialized` - Workflow processing ready
 * `dapr initialized. Status: Running` - Dapr runtime active
 * `Starting worker with task queue: atlan-<package-name>-DEPLOYMENT_NAME` - Worker process started (replace `<package-name>` with your app's package name)
 * `GET /server/ready 200` - Health check endpoint responding

### Verify registration via Atlan UI

Once the App is successfully deployed, it communicates to the Atlan tenant and registers itself. Verify App registration is successful in Atlan:

1. In the same Atlan tenant, navigate to **Workflows** > **Agent**.
2. Look for an entry named `<app_name>-<deployment_name>`, where `<app_name>` matches your selected app (for example, "Oracle" or "Microsoft SQL Server") and `<deployment_name>` is the deployment name you entered when generating the config.
3. Confirm the agent status displays as **Active**.

Agent registration and status takes a couple of minutes to reflect in the Atlan UI.

<h2 id="next-steps">Next steps</h2>

* [Configure workflow execution](https://docs.atlan.com/product/connections/self-deployed-runtime/how-tos/configure-workflow-execution): Set up workflow execution with secret retrieval for your Self-deployed Runtime

---

## Install on Kubernetes - SAP HANA

URL: https://docs.atlan.com/product/connections/self-deployed-runtime/how-tos/install-on-kubernetes
**Connector:** SAP HANA (database)

> Install an App on Kubernetes using Helm charts, Docker images, and specific configuration

:::info **Did you know?** 
SDR requires additional enablement and licensing. Contact your Atlan representative for details.
:::

:::warning Use the guided install wizard instead
**New Self-Deployed Runtime setups are encouraged to use the [guided install wizard](https://docs.atlan.com/product/connections/self-deployed-runtime/how-tos/install-guided).** It assembles a complete guide tailored to your lifecycle mode, platform, and image procurement on a single page—and it's where new setup options (for example, HTTP proxy and custom CA trust) are documented going forward.

This page is kept for existing users who already reference it and may not include the latest steps.
:::

<h2 id="prerequisites">Prerequisites</h2>

Before you begin, make sure you have:

* `kubectl` installed and configured with administrative access to your target Kubernetes cluster
* Helm version 3.0 or later installed on your deployment machine
* A [Docker Hub Personal Access Token (PAT)](https://start.1password.com/open/i?a=WAVUZSKJO5GMNMVBYWAWECXIUE&v=ouvp3xf5334cxoamyiipzjlewy&i=p76avgzmkkcbftldcuvr5jcof4&h=atlanhq.1password.com) from Atlan
* App-specific helm chart name: `{{deploymentValues.helmChartName}}` 
* Object storage: AWS S3, Google Cloud Storage, or Azure Blob Storage with read/write permissions
* Secret store access: AWS Secret Manager, Azure Key Vault, GCP Secret Manager, HashiCorp Vault, or Kubernetes Secrets with read permissions

:::warning For security reasons, the Docker Hub PAT Token is regenerated on a periodic basis. 
In case the token is embedded in automation scripts or CI/CD pipelines, those jobs may fail. 
Contact your Atlan representative for the latest token.
:::

<h2 id="download-required-files">Download required files</h2>

<h3 id="download-helm-chart">Download Helm chart</h3>

Download the Helm chart for the app:

```bash
helm pull oci://registry-1.docker.io/atlanhq/{{deploymentValues.helmChartName}} --untar
```

This unpacks the chart's `Chart.yaml`, `templates/`, and a default `values.yaml` into `./{{deploymentValues.helmChartName}}/`. You'll replace this default `values.yaml` with your Marketplace copy in the next step.

<h3 id="download-values-yaml">Download values.yaml</h3>

Atlan generates the helm `values.yaml` for your runtime directly from the Marketplace UI, including the OAuth client credentials your runtime uses to authenticate to your tenant.

1. Sign in to your Atlan tenant as an administrator, open **Connector** > **Marketplace**, select the app you want to deploy, and click **Download config for Self-Deployed Runtime** in the right-hand sidebar.

2. In the dialog, keep **New deployment** selected (this mints the OAuth client and full config for a fresh runtime), choose **Kubernetes (Helm)** as the deployment target, and enter a **Deployment name**: a short identifier (lowercase letters, digits, and dashes) that identifies this runtime; the agent in **Workflows > Agent** is named `<app_name>-<deployment_name>`.

3. Click **Generate**. Atlan mints a dedicated OAuth client and produces a `values.yaml` file with:
 - `global.atlanBaseUrl`, `global.clientId`, and `global.clientSecret` already filled in.
 - `image.repository`, `image.tag`, and `name` pinned to the active version for your tenant.
 - `objectstore` and `secretstore` placeholders for you to configure below.

<h3 id="replace-chart-values">Replace chart values.yaml</h3>

Replace the default `values.yaml` inside the unpacked chart with the `values.yaml` you downloaded from the Marketplace.

From this point on, all edits to `values.yaml` must be made inside `./{{deploymentValues.helmChartName}}/`.

<h2 id="modify-values-yaml">Modify values.yaml</h2>

### Object storage

Self-Deployed Runtime needs a store for reading or writing files. Configure the object storage that matches your environment:

:::tip Don't see your preferred object store?
If your preferred object store isn't listed here, [reach out to Atlan support](https://docs.atlan.com/support/submit-request). Support for additional object stores may be available.
:::

<Tabs>
<TabItem value="aws-s3" label="AWS S3" default>

**Required permissions:**

Apply object-level actions to `arn:aws:s3:::BUCKET/*` and the list action to `arn:aws:s3:::BUCKET` in separate IAM statement entries.

| IAM action | Operations covered |
|---|---|
| `s3:GetObject` | GetObject (full and byte-range), HeadObject |
| `s3:PutObject` | PutObject, CreateMultipartUpload, UploadPart, CompleteMultipartUpload |
| `s3:AbortMultipartUpload` | Abort in-flight multipart upload on error (required for streaming write error paths) |
| `s3:DeleteObject` | DeleteObject and DeleteObjects (bulk batch—same IAM action) |
| `s3:ListBucket` | ListObjectsV2—bucket-level permission, not object-level |

```json
{
 "Version": "2012-10-17",
 "Statement": [
 {
 "Effect": "Allow",
 "Action": [
 "s3:GetObject",
 "s3:PutObject",
 "s3:AbortMultipartUpload",
 "s3:DeleteObject"
 ],
 "Resource": "arn:aws:s3:::YOUR-BUCKET/*"
 },
 {
 "Effect": "Allow",
 "Action": "s3:ListBucket",
 "Resource": "arn:aws:s3:::YOUR-BUCKET"
 }
 ]
}
```

**AssumeRole**: when using `assumeRoleArn`, the caller identity additionally needs `sts:AssumeRole` on the target role ARN. The role itself holds the bucket policy described earlier.

**Configure:**

 1. Locate the `objectstore` attribute in `values.yaml`.
 2. Add AWS S3 configuration. For more information, see [AWS S3 Binding Spec](https://docs.dapr.io/reference/components-reference/supported-bindings/s3/).

 ```yaml
 objectstore:
 enabled: true
 spec:
 type: bindings.aws.s3
 version: v1
 metadata:
 - name: accessKey #optional, leave this empty for iam authentication
 value: ""
 - name: secretKey #optional, leave this empty for iam authentication
 value: ""
 - name: bucket #required, name of the bucket where application can write
 value: "<bucket-name>"
 - name: region #required, region of the bucket where application can write
 value: "<bucket-region>"
 - name: forcePathStyle
 value: "true"
 ```

</TabItem>
<TabItem value="gcp-storage" label="Google Cloud Storage">

**Required permissions:**

| IAM permission | Operations covered |
|---|---|
| `storage.objects.get` | GetObject (full and byte-range), object metadata / HeadObject equivalent |
| `storage.objects.create` | PutObject, resumable / streaming write |
| `storage.objects.delete` | DeleteObject (GCS has no native bulk-delete API—`delete_prefix` issues parallel single-object deletes) |
| `storage.objects.list` | ListObjects |

No `storage.buckets.*` permissions are needed. The smallest predefined role that covers all four is **`roles/storage.objectAdmin`** scoped to the bucket. Alternatively, create a custom role with exactly these four permissions.

**Configure:**

 1. Locate the `objectstore` attribute in `values.yaml`.
 2. Add Google Cloud Storage configuration. For more information, see [GCP Storage Bucket binding spec](https://docs.dapr.io/reference/components-reference/supported-bindings/gcpbucket/)

 ```yaml
 objectstore:
 enabled: true
 spec:
 type: bindings.gcp.bucket
 version: v1
 metadata:
 - name: bucket
 value: "your-gcs-bucket-name"
 - name: type
 value: "service_account"
 - name: project_id
 value: "your-gcp-project-id"
 ```

</TabItem>
<TabItem value="azure-blob" label="Azure Blob Storage">

**Required permissions:**

**RBAC**—assign at container or storage-account scope:

| RBAC action | Operations covered |
|---|---|
| `Microsoft.Storage/storageAccounts/blobServices/containers/blobs/read` | GetBlob, GetBlobProperties (HEAD), ListBlobs, byte-range GET |
| `Microsoft.Storage/storageAccounts/blobServices/containers/blobs/write` | PutBlob, PutBlock + PutBlockList (streaming / block write) |
| `Microsoft.Storage/storageAccounts/blobServices/containers/blobs/delete` | DeleteBlob, BlobBatch delete (bulk—up to 256 keys per request) |

The smallest predefined role covering all three is **`Storage Blob Data Contributor`**. `Storage Blob Data Owner` is a superset and is only needed if you additionally require POSIX ACL management on ADLS Gen2.

**SAS token**—minimum permissions at container scope: `r` (read) + `w` (write) + `d` (delete) + `l` (list), that is a container-scoped SAS with **`rwdl`**.

**ADLS Gen2 with POSIX ACLs**: if the storage account has hierarchical namespace enabled and you use ACL-based access control instead of RBAC, the principal needs Execute (`X`) on every parent directory and Read / Write / Delete on the objects in scope. RBAC (`Storage Blob Data Contributor`) is simpler and is recommended unless you have a specific ACL requirement.

**Configure:**

 1. Locate the `objectstore` attribute in `values.yaml`.
 2. Add Azure Blob Storage configuration. For more information, see [Azure Blob Storage binding spec](https://docs.dapr.io/reference/components-reference/supported-bindings/blobstorage/)

 ```yaml
 objectstore:
 enabled: true
 spec:
 type: bindings.azure.blobstorage
 version: v1
 metadata:
 - name: accountName
 value: "your-storage-account-name"
 - name: accountKey
 value: "your-storage-account-key"
 - name: containerName
 value: "your-container-name"
 ```

</TabItem>
</Tabs>

### Secret storage

Self-Deployed Runtime fetches secrets from a secret store to connect to the source systems. The secret store references are used to configure the workflow. Configure the secret store that aligns with your security infrastructure:

:::info Did you know?
Dapr supports additional secret stores which aren't mentioned here. For more information, see [Dapr secret store documentation](https://docs.dapr.io/reference/components-reference/supported-secret-stores/) for other configurations.
:::

:::warning Secret content format and naming
When storing credentials, follow the [secret naming and format requirements](https://docs.atlan.com/product/connections/self-deployed-runtime/how-tos/configure-workflow-execution#secret-content-format).
:::

<Tabs>
<TabItem value="aws-secret-manager" label="AWS Secret Manager" default>
 
 1. Locate the `secretstore` attribute in `values.yaml`.
 2. Add AWS Secret Manager configuration. For more information, see [AWS Secrets Manager](https://docs.dapr.io/reference/components-reference/supported-secret-stores/aws-secret-manager/)

 ```yaml
 secretstore:
 enabled: true
 spec:
 type: secretstores.aws.secretmanager
 version: v1
 metadata:
 - name: region # required, region in which secret is hosted
 value: <secret-region>
 # Needed if IAM authentication is not used
 - name: accessKey
 value: ""
 - name: secretKey
 value: ""
 ```

If you are using IAM role / IRSA authentication, leave `accessKey` and `secretKey` empty.

If you are using an IAM user instead, set:
- `accessKey` to the IAM user's access key ID
- `secretKey` to the IAM user's secret access key

That IAM user must have permission to read the target secret from AWS Secrets Manager:

```json
{
 "Version": "2012-10-17",
 "Statement": [
 {
 "Effect": "Allow",
 "Action": [
 "secretsmanager:GetSecretValue",
 "secretsmanager:DescribeSecret"
 ],
 "Resource": "arn:aws:secretsmanager:<region>:<account-id>:secret:<secret-name>*"
 }
 ]
}
```

:::note
Include the trailing `*` in the secret ARN. AWS appends a random suffix to secret names in the ARN, so omitting it can cause access failures.
:::

</TabItem>
<TabItem value="azure-key-vault" label="Azure Key Vault">

 1. Locate the `secretstore` attribute in `values.yaml`.
 2. Add Azure Key Vault configuration. For more information, see [Azure Key Vault secret store](https://docs.dapr.io/reference/components-reference/supported-secret-stores/azure-keyvault/)

 ```yaml
 secretstore:
 enabled: true
 spec:
 type: secretstores.azure.keyvault
 version: v1
 metadata:
 - name: vaultName
 value: "<your-keyvault-name>"
 - name: azureTenantId
 value: "<your-tenant-id>"
 - name: azureClientId
 value: "<your-client-id>"
 - name: azureClientSecret
 value: "<your-client-secret>"
 - name: azureEnvironment
 value: "AZUREPUBLICCLOUD" # Optional: AZUREPUBLICCLOUD, AZURECHINACLOUD, AZUREUSGOVERNMENTCLOUD, AZUREGERMANCLOUD
 ```
 Azure Key Vault supports multiple authentication methods:
 - **Client Secret**: Use `azureClientSecret` with tenant ID and client ID
 - **Certificate**: Use `azureCertificateFile` instead of client secret
 - **Managed Identity**: Omit authentication fields and use Azure managed identity

 For detailed authentication setup, see the [Authenticating to Azure](https://docs.dapr.io/developing-applications/integrations/azure/azure-authentication/authenticating-azure/) documentation.

</TabItem>
<TabItem value="gcp-secret-manager" label="GCP Secret Manager">

1. Locate the `secretstore` attribute in `values.yaml`.
2. Add Google Cloud Secret Manager configuration. For more information, see [GCP Secret Manager](https://docs.dapr.io/reference/components-reference/supported-secret-stores/gcp-secret-manager/)

 The GCP service account used in this configuration must have the `Secret Manager Secret Accessor` role (`roles/secretmanager.secretAccessor`) on the project where your secrets are stored. The metadata values below come from the service account's JSON key file.

 ```yaml
 secretstore:
 enabled: true
 spec:
 type: secretstores.gcp.secretmanager
 version: v1
 metadata:
 - name: type
 value: "service_account"
 - name: project_id
 value: "<project-id>"
 - name: private_key_id
 value: "<private-key-id>"
 - name: private_key
 value: "<private-key>"
 - name: client_email
 value: "<client-email>"
 - name: client_id
 value: "<client-id>"
 - name: auth_uri
 value: "https://accounts.google.com/o/oauth2/auth"
 - name: token_uri
 value: "https://oauth2.googleapis.com/token"
 - name: auth_provider_x509_cert_url
 value: "https://www.googleapis.com/oauth2/v1/certs"
 - name: client_x509_cert_url
 value: "https://www.googleapis.com/robot/v1/metadata/x509/<client-email>"
 ```

</TabItem>
<TabItem value="hashicorp-vault" label="HashiCorp Vault">

1. Locate the `secretstore` attribute in `values.yaml`.
2. Add HashiCorp Vault configuration. For more information, see [HashiCorp Vault](https://docs.dapr.io/reference/components-reference/supported-secret-stores/hashicorp-vault/)

 ```yaml
 secretstore:
 enabled: true
 spec:
 type: secretstores.hashicorp.vault
 version: v1
 metadata:
 - name: vaultAddr
 value: "[vault_address]" # Optional. Default: "https://127.0.0.1:8200"
 - name: caCert # Optional. This or caPath or caPem
 value: "[ca_cert]"
 - name: caPath # Optional. This or CaCert or caPem
 value: "[path_to_ca_cert_file]"
 - name: caPem # Optional. This or CaCert or CaPath
 value: "[encoded_ca_cert_pem]"
 - name: skipVerify # Optional. Default: false
 value: "[skip_tls_verification]"
 - name: tlsServerName # Optional.
 value: "[tls_config_server_name]"
 - name: vaultTokenMountPath # Required if vaultToken not provided. Path to token file.
 value: "[path_to_file_containing_token]"
 - name: vaultToken # Required if vaultTokenMountPath not provided. Token value.
 value: "[vault_token]"
 - name: vaultKVPrefix # Optional. Default: "dapr"
 value: "[vault_prefix]"
 - name: vaultKVUsePrefix # Optional. default: "true"
 value: "[true/false]"
 - name: enginePath # Optional. default: "secret"
 value: "secret"
 - name: vaultValueType # Optional. default: "map"
 value: "map"
 ```

</TabItem>
<TabItem value="kubernetes-secrets" label="Kubernetes Secrets">

1. Locate the `secretstore` attribute in `values.yaml`.
2. Add Kubernetes native secret storage. For more information, see [Kubernetes secrets](https://docs.dapr.io/reference/components-reference/supported-secret-stores/kubernetes-secret-store/)

 ```yaml
 secretstore:
 enabled: true
 spec:
 type: secretstores.kubernetes
 version: v1
 metadata:
 - name: defaultNamespace
 value: "default" # Optional: Default namespace to retrieve secrets from
 - name: kubeconfigPath
 value: "/path/to/kubeconfig" # Optional: Path to kubeconfig file
 ```
 When Dapr is deployed to a Kubernetes cluster, a secret store with the name `kubernetes` is automatically provisioned. You can use this native Kubernetes secret store with no need to create, deploy or maintain a component configuration file.

</TabItem>
<TabItem value="environment-variable-based" label="Environment Variables">

1. Locate the `secretstore` attribute in `values.yaml`.
2. Add Local environment variables as the spec. For more information, see [Local Environment Variables](https://docs.dapr.io/reference/components-reference/supported-secret-stores/envvar-secret-store/)

 ```yaml
 secretstore:
 enabled: true
 spec:
 type: secretstores.local.env
 version: v1
 ```

</TabItem>
</Tabs>

### Image source

Choose how the cluster pulls the app image. Most installs use Atlan's Docker Hub directly; mirror to a private registry if your organization requires it.

<Tabs>
<TabItem value="docker-hub" label="Public Docker Hub" default>

The chart pulls the app image from Atlan's Docker Hub at runtime. The pod needs a Kubernetes secret containing your Docker Hub PAT to authenticate:

```bash
kubectl create secret docker-registry atlan-docker-secret \
 --docker-server=docker.io \
 --docker-username=YOUR_USERNAME \
 --docker-password=YOUR_PAT_TOKEN \
 -n <namespace>
```

- Replace `YOUR_USERNAME` with the Docker Hub username provided by Atlan.
- Replace `YOUR_PAT_TOKEN` with the Personal Access Token (PAT) provided by Atlan.
- Replace `<namespace>` with the namespace you need to install the chart into. The secret and the release must live in the same namespace, or the pod fails with `ImagePullBackOff`.

The downloaded `values.yaml` already references this secret under `imagePullSecrets`. If you use a different secret name, update that field in the file.

</TabItem>
<TabItem value="private-registry" label="Private image repo">

Mirror the Atlan image to your enterprise registry and update `values.yaml` to point at it.

1. Authenticate with Docker Hub using the PAT from Atlan, then pull the source image. The image and tag come from `image.repository` and `image.tag` in the downloaded `values.yaml`:

 ```bash
 docker login -u atlanhq
 # When prompted for password, enter the PAT provided by Atlan
 docker pull <image.repository>:<image.tag>
 ```

2. Push the image to your enterprise's registry. Note down the new repository name and image tag.

3. Update `image.repository` and `image.tag` in `values.yaml` with the new values.

4. If your private registry requires authentication, create an image-pull secret in the target namespace and set `imagePullSecrets` in `values.yaml` to its name.

</TabItem>
</Tabs>

<h2 id="deploy-app">Deploy app</h2>

Follow these steps to deploy the secure app:

* Install the helm chart. The chart directory now carries your edited `values.yaml`, so no `-f` flag is needed:

 ```bash
 helm install {{deploymentValues.helmChartName}}-release ./{{deploymentValues.helmChartName}} -n <namespace>
 ```

 - Replace `<namespace>` with your target Kubernetes namespace.
 - The helm chart name `{{deploymentValues.helmChartName}}` is automatically used from your selected app.

The deployment process typically takes a few minutes to complete depending on factors like Kubernetes cluster resource availability, private image repository download time etc.

<h2 id="verify-app">Verify app</h2>

Follow these steps to verify deployment:

### Verify deployment status on cluster

1. Check pod status:

 ```bash
 kubectl get pods -n <namespace>
 ```

 The output appears similar to:

 ```
 NAME READY STATUS RESTARTS AGE
 <helm-chart-name>-release-<helm-chart-name>-5dff95cd85-cvk5z 1/1 Running 0 2m
 ```
 
 Replace `<helm-chart-name>` with your app's helm chart name (shown in the prerequisites section earlier in this guide).

 The pod status shows `Running` with `1/1` ready containers.

2. Verify logs for the running pod
 
 ```bash
 kubectl logs -n <namespace> -l app.kubernetes.io/name={{deploymentValues.helmChartName}} --tail=50 -f
 ```
 **Example application logs**: Look for these key log messages that confirm successful deployment:

 * `Uvicorn running on http://0.0.0.0:8000` - Web server started
 * `Workflow engine initialized` - Workflow processing ready
 * `dapr initialized. Status: Running` - Dapr runtime active
 * `Starting worker with task queue: atlan-<package-name>-DEPLOYMENT_NAME` - Worker process started (replace `<package-name>` with your app's package name)
 * `GET /server/ready 200` - Health check endpoint responding

### Verify registration via Atlan UI

Once the App is successfully deployed, it communicates to the Atlan tenant and registers itself. Verify App registration is successful in Atlan:

1. In the same Atlan tenant, navigate to **Workflows** > **Agent**.
2. Look for an entry named `<app_name>-<deployment_name>`, where `<app_name>` matches your selected app (for example, "Oracle" or "Microsoft SQL Server") and `<deployment_name>` is the deployment name you entered when generating the config.
3. Confirm the agent status displays as **Active**.

Agent registration and status takes a couple of minutes to reflect in the Atlan UI.

<h2 id="next-steps">Next steps</h2>

* [Configure workflow execution](https://docs.atlan.com/product/connections/self-deployed-runtime/how-tos/configure-workflow-execution): Set up workflow execution with secret retrieval for your Self-deployed Runtime

---

## Install on Kubernetes - Starburst Enterprise

URL: https://docs.atlan.com/product/connections/self-deployed-runtime/how-tos/install-on-kubernetes
**Connector:** Starburst Enterprise (database)

> Install an App on Kubernetes using Helm charts, Docker images, and specific configuration

:::info **Did you know?** 
SDR requires additional enablement and licensing. Contact your Atlan representative for details.
:::

:::warning Use the guided install wizard instead
**New Self-Deployed Runtime setups are encouraged to use the [guided install wizard](https://docs.atlan.com/product/connections/self-deployed-runtime/how-tos/install-guided).** It assembles a complete guide tailored to your lifecycle mode, platform, and image procurement on a single page—and it's where new setup options (for example, HTTP proxy and custom CA trust) are documented going forward.

This page is kept for existing users who already reference it and may not include the latest steps.
:::

<h2 id="prerequisites">Prerequisites</h2>

Before you begin, make sure you have:

* `kubectl` installed and configured with administrative access to your target Kubernetes cluster
* Helm version 3.0 or later installed on your deployment machine
* A [Docker Hub Personal Access Token (PAT)](https://start.1password.com/open/i?a=WAVUZSKJO5GMNMVBYWAWECXIUE&v=ouvp3xf5334cxoamyiipzjlewy&i=p76avgzmkkcbftldcuvr5jcof4&h=atlanhq.1password.com) from Atlan
* App-specific helm chart name: `{{deploymentValues.helmChartName}}` 
* Object storage: AWS S3, Google Cloud Storage, or Azure Blob Storage with read/write permissions
* Secret store access: AWS Secret Manager, Azure Key Vault, GCP Secret Manager, HashiCorp Vault, or Kubernetes Secrets with read permissions

:::warning For security reasons, the Docker Hub PAT Token is regenerated on a periodic basis. 
In case the token is embedded in automation scripts or CI/CD pipelines, those jobs may fail. 
Contact your Atlan representative for the latest token.
:::

<h2 id="download-required-files">Download required files</h2>

<h3 id="download-helm-chart">Download Helm chart</h3>

Download the Helm chart for the app:

```bash
helm pull oci://registry-1.docker.io/atlanhq/{{deploymentValues.helmChartName}} --untar
```

This unpacks the chart's `Chart.yaml`, `templates/`, and a default `values.yaml` into `./{{deploymentValues.helmChartName}}/`. You'll replace this default `values.yaml` with your Marketplace copy in the next step.

<h3 id="download-values-yaml">Download values.yaml</h3>

Atlan generates the helm `values.yaml` for your runtime directly from the Marketplace UI, including the OAuth client credentials your runtime uses to authenticate to your tenant.

1. Sign in to your Atlan tenant as an administrator, open **Connector** > **Marketplace**, select the app you want to deploy, and click **Download config for Self-Deployed Runtime** in the right-hand sidebar.

2. In the dialog, keep **New deployment** selected (this mints the OAuth client and full config for a fresh runtime), choose **Kubernetes (Helm)** as the deployment target, and enter a **Deployment name**: a short identifier (lowercase letters, digits, and dashes) that identifies this runtime; the agent in **Workflows > Agent** is named `<app_name>-<deployment_name>`.

3. Click **Generate**. Atlan mints a dedicated OAuth client and produces a `values.yaml` file with:
 - `global.atlanBaseUrl`, `global.clientId`, and `global.clientSecret` already filled in.
 - `image.repository`, `image.tag`, and `name` pinned to the active version for your tenant.
 - `objectstore` and `secretstore` placeholders for you to configure below.

<h3 id="replace-chart-values">Replace chart values.yaml</h3>

Replace the default `values.yaml` inside the unpacked chart with the `values.yaml` you downloaded from the Marketplace.

From this point on, all edits to `values.yaml` must be made inside `./{{deploymentValues.helmChartName}}/`.

<h2 id="modify-values-yaml">Modify values.yaml</h2>

### Object storage

Self-Deployed Runtime needs a store for reading or writing files. Configure the object storage that matches your environment:

:::tip Don't see your preferred object store?
If your preferred object store isn't listed here, [reach out to Atlan support](https://docs.atlan.com/support/submit-request). Support for additional object stores may be available.
:::

<Tabs>
<TabItem value="aws-s3" label="AWS S3" default>

**Required permissions:**

Apply object-level actions to `arn:aws:s3:::BUCKET/*` and the list action to `arn:aws:s3:::BUCKET` in separate IAM statement entries.

| IAM action | Operations covered |
|---|---|
| `s3:GetObject` | GetObject (full and byte-range), HeadObject |
| `s3:PutObject` | PutObject, CreateMultipartUpload, UploadPart, CompleteMultipartUpload |
| `s3:AbortMultipartUpload` | Abort in-flight multipart upload on error (required for streaming write error paths) |
| `s3:DeleteObject` | DeleteObject and DeleteObjects (bulk batch—same IAM action) |
| `s3:ListBucket` | ListObjectsV2—bucket-level permission, not object-level |

```json
{
 "Version": "2012-10-17",
 "Statement": [
 {
 "Effect": "Allow",
 "Action": [
 "s3:GetObject",
 "s3:PutObject",
 "s3:AbortMultipartUpload",
 "s3:DeleteObject"
 ],
 "Resource": "arn:aws:s3:::YOUR-BUCKET/*"
 },
 {
 "Effect": "Allow",
 "Action": "s3:ListBucket",
 "Resource": "arn:aws:s3:::YOUR-BUCKET"
 }
 ]
}
```

**AssumeRole**: when using `assumeRoleArn`, the caller identity additionally needs `sts:AssumeRole` on the target role ARN. The role itself holds the bucket policy described earlier.

**Configure:**

 1. Locate the `objectstore` attribute in `values.yaml`.
 2. Add AWS S3 configuration. For more information, see [AWS S3 Binding Spec](https://docs.dapr.io/reference/components-reference/supported-bindings/s3/).

 ```yaml
 objectstore:
 enabled: true
 spec:
 type: bindings.aws.s3
 version: v1
 metadata:
 - name: accessKey #optional, leave this empty for iam authentication
 value: ""
 - name: secretKey #optional, leave this empty for iam authentication
 value: ""
 - name: bucket #required, name of the bucket where application can write
 value: "<bucket-name>"
 - name: region #required, region of the bucket where application can write
 value: "<bucket-region>"
 - name: forcePathStyle
 value: "true"
 ```

</TabItem>
<TabItem value="gcp-storage" label="Google Cloud Storage">

**Required permissions:**

| IAM permission | Operations covered |
|---|---|
| `storage.objects.get` | GetObject (full and byte-range), object metadata / HeadObject equivalent |
| `storage.objects.create` | PutObject, resumable / streaming write |
| `storage.objects.delete` | DeleteObject (GCS has no native bulk-delete API—`delete_prefix` issues parallel single-object deletes) |
| `storage.objects.list` | ListObjects |

No `storage.buckets.*` permissions are needed. The smallest predefined role that covers all four is **`roles/storage.objectAdmin`** scoped to the bucket. Alternatively, create a custom role with exactly these four permissions.

**Configure:**

 1. Locate the `objectstore` attribute in `values.yaml`.
 2. Add Google Cloud Storage configuration. For more information, see [GCP Storage Bucket binding spec](https://docs.dapr.io/reference/components-reference/supported-bindings/gcpbucket/)

 ```yaml
 objectstore:
 enabled: true
 spec:
 type: bindings.gcp.bucket
 version: v1
 metadata:
 - name: bucket
 value: "your-gcs-bucket-name"
 - name: type
 value: "service_account"
 - name: project_id
 value: "your-gcp-project-id"
 ```

</TabItem>
<TabItem value="azure-blob" label="Azure Blob Storage">

**Required permissions:**

**RBAC**—assign at container or storage-account scope:

| RBAC action | Operations covered |
|---|---|
| `Microsoft.Storage/storageAccounts/blobServices/containers/blobs/read` | GetBlob, GetBlobProperties (HEAD), ListBlobs, byte-range GET |
| `Microsoft.Storage/storageAccounts/blobServices/containers/blobs/write` | PutBlob, PutBlock + PutBlockList (streaming / block write) |
| `Microsoft.Storage/storageAccounts/blobServices/containers/blobs/delete` | DeleteBlob, BlobBatch delete (bulk—up to 256 keys per request) |

The smallest predefined role covering all three is **`Storage Blob Data Contributor`**. `Storage Blob Data Owner` is a superset and is only needed if you additionally require POSIX ACL management on ADLS Gen2.

**SAS token**—minimum permissions at container scope: `r` (read) + `w` (write) + `d` (delete) + `l` (list), that is a container-scoped SAS with **`rwdl`**.

**ADLS Gen2 with POSIX ACLs**: if the storage account has hierarchical namespace enabled and you use ACL-based access control instead of RBAC, the principal needs Execute (`X`) on every parent directory and Read / Write / Delete on the objects in scope. RBAC (`Storage Blob Data Contributor`) is simpler and is recommended unless you have a specific ACL requirement.

**Configure:**

 1. Locate the `objectstore` attribute in `values.yaml`.
 2. Add Azure Blob Storage configuration. For more information, see [Azure Blob Storage binding spec](https://docs.dapr.io/reference/components-reference/supported-bindings/blobstorage/)

 ```yaml
 objectstore:
 enabled: true
 spec:
 type: bindings.azure.blobstorage
 version: v1
 metadata:
 - name: accountName
 value: "your-storage-account-name"
 - name: accountKey
 value: "your-storage-account-key"
 - name: containerName
 value: "your-container-name"
 ```

</TabItem>
</Tabs>

### Secret storage

Self-Deployed Runtime fetches secrets from a secret store to connect to the source systems. The secret store references are used to configure the workflow. Configure the secret store that aligns with your security infrastructure:

:::info Did you know?
Dapr supports additional secret stores which aren't mentioned here. For more information, see [Dapr secret store documentation](https://docs.dapr.io/reference/components-reference/supported-secret-stores/) for other configurations.
:::

:::warning Secret content format and naming
When storing credentials, follow the [secret naming and format requirements](https://docs.atlan.com/product/connections/self-deployed-runtime/how-tos/configure-workflow-execution#secret-content-format).
:::

<Tabs>
<TabItem value="aws-secret-manager" label="AWS Secret Manager" default>
 
 1. Locate the `secretstore` attribute in `values.yaml`.
 2. Add AWS Secret Manager configuration. For more information, see [AWS Secrets Manager](https://docs.dapr.io/reference/components-reference/supported-secret-stores/aws-secret-manager/)

 ```yaml
 secretstore:
 enabled: true
 spec:
 type: secretstores.aws.secretmanager
 version: v1
 metadata:
 - name: region # required, region in which secret is hosted
 value: <secret-region>
 # Needed if IAM authentication is not used
 - name: accessKey
 value: ""
 - name: secretKey
 value: ""
 ```

If you are using IAM role / IRSA authentication, leave `accessKey` and `secretKey` empty.

If you are using an IAM user instead, set:
- `accessKey` to the IAM user's access key ID
- `secretKey` to the IAM user's secret access key

That IAM user must have permission to read the target secret from AWS Secrets Manager:

```json
{
 "Version": "2012-10-17",
 "Statement": [
 {
 "Effect": "Allow",
 "Action": [
 "secretsmanager:GetSecretValue",
 "secretsmanager:DescribeSecret"
 ],
 "Resource": "arn:aws:secretsmanager:<region>:<account-id>:secret:<secret-name>*"
 }
 ]
}
```

:::note
Include the trailing `*` in the secret ARN. AWS appends a random suffix to secret names in the ARN, so omitting it can cause access failures.
:::

</TabItem>
<TabItem value="azure-key-vault" label="Azure Key Vault">

 1. Locate the `secretstore` attribute in `values.yaml`.
 2. Add Azure Key Vault configuration. For more information, see [Azure Key Vault secret store](https://docs.dapr.io/reference/components-reference/supported-secret-stores/azure-keyvault/)

 ```yaml
 secretstore:
 enabled: true
 spec:
 type: secretstores.azure.keyvault
 version: v1
 metadata:
 - name: vaultName
 value: "<your-keyvault-name>"
 - name: azureTenantId
 value: "<your-tenant-id>"
 - name: azureClientId
 value: "<your-client-id>"
 - name: azureClientSecret
 value: "<your-client-secret>"
 - name: azureEnvironment
 value: "AZUREPUBLICCLOUD" # Optional: AZUREPUBLICCLOUD, AZURECHINACLOUD, AZUREUSGOVERNMENTCLOUD, AZUREGERMANCLOUD
 ```
 Azure Key Vault supports multiple authentication methods:
 - **Client Secret**: Use `azureClientSecret` with tenant ID and client ID
 - **Certificate**: Use `azureCertificateFile` instead of client secret
 - **Managed Identity**: Omit authentication fields and use Azure managed identity

 For detailed authentication setup, see the [Authenticating to Azure](https://docs.dapr.io/developing-applications/integrations/azure/azure-authentication/authenticating-azure/) documentation.

</TabItem>
<TabItem value="gcp-secret-manager" label="GCP Secret Manager">

1. Locate the `secretstore` attribute in `values.yaml`.
2. Add Google Cloud Secret Manager configuration. For more information, see [GCP Secret Manager](https://docs.dapr.io/reference/components-reference/supported-secret-stores/gcp-secret-manager/)

 The GCP service account used in this configuration must have the `Secret Manager Secret Accessor` role (`roles/secretmanager.secretAccessor`) on the project where your secrets are stored. The metadata values below come from the service account's JSON key file.

 ```yaml
 secretstore:
 enabled: true
 spec:
 type: secretstores.gcp.secretmanager
 version: v1
 metadata:
 - name: type
 value: "service_account"
 - name: project_id
 value: "<project-id>"
 - name: private_key_id
 value: "<private-key-id>"
 - name: private_key
 value: "<private-key>"
 - name: client_email
 value: "<client-email>"
 - name: client_id
 value: "<client-id>"
 - name: auth_uri
 value: "https://accounts.google.com/o/oauth2/auth"
 - name: token_uri
 value: "https://oauth2.googleapis.com/token"
 - name: auth_provider_x509_cert_url
 value: "https://www.googleapis.com/oauth2/v1/certs"
 - name: client_x509_cert_url
 value: "https://www.googleapis.com/robot/v1/metadata/x509/<client-email>"
 ```

</TabItem>
<TabItem value="hashicorp-vault" label="HashiCorp Vault">

1. Locate the `secretstore` attribute in `values.yaml`.
2. Add HashiCorp Vault configuration. For more information, see [HashiCorp Vault](https://docs.dapr.io/reference/components-reference/supported-secret-stores/hashicorp-vault/)

 ```yaml
 secretstore:
 enabled: true
 spec:
 type: secretstores.hashicorp.vault
 version: v1
 metadata:
 - name: vaultAddr
 value: "[vault_address]" # Optional. Default: "https://127.0.0.1:8200"
 - name: caCert # Optional. This or caPath or caPem
 value: "[ca_cert]"
 - name: caPath # Optional. This or CaCert or caPem
 value: "[path_to_ca_cert_file]"
 - name: caPem # Optional. This or CaCert or CaPath
 value: "[encoded_ca_cert_pem]"
 - name: skipVerify # Optional. Default: false
 value: "[skip_tls_verification]"
 - name: tlsServerName # Optional.
 value: "[tls_config_server_name]"
 - name: vaultTokenMountPath # Required if vaultToken not provided. Path to token file.
 value: "[path_to_file_containing_token]"
 - name: vaultToken # Required if vaultTokenMountPath not provided. Token value.
 value: "[vault_token]"
 - name: vaultKVPrefix # Optional. Default: "dapr"
 value: "[vault_prefix]"
 - name: vaultKVUsePrefix # Optional. default: "true"
 value: "[true/false]"
 - name: enginePath # Optional. default: "secret"
 value: "secret"
 - name: vaultValueType # Optional. default: "map"
 value: "map"
 ```

</TabItem>
<TabItem value="kubernetes-secrets" label="Kubernetes Secrets">

1. Locate the `secretstore` attribute in `values.yaml`.
2. Add Kubernetes native secret storage. For more information, see [Kubernetes secrets](https://docs.dapr.io/reference/components-reference/supported-secret-stores/kubernetes-secret-store/)

 ```yaml
 secretstore:
 enabled: true
 spec:
 type: secretstores.kubernetes
 version: v1
 metadata:
 - name: defaultNamespace
 value: "default" # Optional: Default namespace to retrieve secrets from
 - name: kubeconfigPath
 value: "/path/to/kubeconfig" # Optional: Path to kubeconfig file
 ```
 When Dapr is deployed to a Kubernetes cluster, a secret store with the name `kubernetes` is automatically provisioned. You can use this native Kubernetes secret store with no need to create, deploy or maintain a component configuration file.

</TabItem>
<TabItem value="environment-variable-based" label="Environment Variables">

1. Locate the `secretstore` attribute in `values.yaml`.
2. Add Local environment variables as the spec. For more information, see [Local Environment Variables](https://docs.dapr.io/reference/components-reference/supported-secret-stores/envvar-secret-store/)

 ```yaml
 secretstore:
 enabled: true
 spec:
 type: secretstores.local.env
 version: v1
 ```

</TabItem>
</Tabs>

### Image source

Choose how the cluster pulls the app image. Most installs use Atlan's Docker Hub directly; mirror to a private registry if your organization requires it.

<Tabs>
<TabItem value="docker-hub" label="Public Docker Hub" default>

The chart pulls the app image from Atlan's Docker Hub at runtime. The pod needs a Kubernetes secret containing your Docker Hub PAT to authenticate:

```bash
kubectl create secret docker-registry atlan-docker-secret \
 --docker-server=docker.io \
 --docker-username=YOUR_USERNAME \
 --docker-password=YOUR_PAT_TOKEN \
 -n <namespace>
```

- Replace `YOUR_USERNAME` with the Docker Hub username provided by Atlan.
- Replace `YOUR_PAT_TOKEN` with the Personal Access Token (PAT) provided by Atlan.
- Replace `<namespace>` with the namespace you need to install the chart into. The secret and the release must live in the same namespace, or the pod fails with `ImagePullBackOff`.

The downloaded `values.yaml` already references this secret under `imagePullSecrets`. If you use a different secret name, update that field in the file.

</TabItem>
<TabItem value="private-registry" label="Private image repo">

Mirror the Atlan image to your enterprise registry and update `values.yaml` to point at it.

1. Authenticate with Docker Hub using the PAT from Atlan, then pull the source image. The image and tag come from `image.repository` and `image.tag` in the downloaded `values.yaml`:

 ```bash
 docker login -u atlanhq
 # When prompted for password, enter the PAT provided by Atlan
 docker pull <image.repository>:<image.tag>
 ```

2. Push the image to your enterprise's registry. Note down the new repository name and image tag.

3. Update `image.repository` and `image.tag` in `values.yaml` with the new values.

4. If your private registry requires authentication, create an image-pull secret in the target namespace and set `imagePullSecrets` in `values.yaml` to its name.

</TabItem>
</Tabs>

<h2 id="deploy-app">Deploy app</h2>

Follow these steps to deploy the secure app:

* Install the helm chart. The chart directory now carries your edited `values.yaml`, so no `-f` flag is needed:

 ```bash
 helm install {{deploymentValues.helmChartName}}-release ./{{deploymentValues.helmChartName}} -n <namespace>
 ```

 - Replace `<namespace>` with your target Kubernetes namespace.
 - The helm chart name `{{deploymentValues.helmChartName}}` is automatically used from your selected app.

The deployment process typically takes a few minutes to complete depending on factors like Kubernetes cluster resource availability, private image repository download time etc.

<h2 id="verify-app">Verify app</h2>

Follow these steps to verify deployment:

### Verify deployment status on cluster

1. Check pod status:

 ```bash
 kubectl get pods -n <namespace>
 ```

 The output appears similar to:

 ```
 NAME READY STATUS RESTARTS AGE
 <helm-chart-name>-release-<helm-chart-name>-5dff95cd85-cvk5z 1/1 Running 0 2m
 ```
 
 Replace `<helm-chart-name>` with your app's helm chart name (shown in the prerequisites section earlier in this guide).

 The pod status shows `Running` with `1/1` ready containers.

2. Verify logs for the running pod
 
 ```bash
 kubectl logs -n <namespace> -l app.kubernetes.io/name={{deploymentValues.helmChartName}} --tail=50 -f
 ```
 **Example application logs**: Look for these key log messages that confirm successful deployment:

 * `Uvicorn running on http://0.0.0.0:8000` - Web server started
 * `Workflow engine initialized` - Workflow processing ready
 * `dapr initialized. Status: Running` - Dapr runtime active
 * `Starting worker with task queue: atlan-<package-name>-DEPLOYMENT_NAME` - Worker process started (replace `<package-name>` with your app's package name)
 * `GET /server/ready 200` - Health check endpoint responding

### Verify registration via Atlan UI

Once the App is successfully deployed, it communicates to the Atlan tenant and registers itself. Verify App registration is successful in Atlan:

1. In the same Atlan tenant, navigate to **Workflows** > **Agent**.
2. Look for an entry named `<app_name>-<deployment_name>`, where `<app_name>` matches your selected app (for example, "Oracle" or "Microsoft SQL Server") and `<deployment_name>` is the deployment name you entered when generating the config.
3. Confirm the agent status displays as **Active**.

Agent registration and status takes a couple of minutes to reflect in the Atlan UI.

<h2 id="next-steps">Next steps</h2>

* [Configure workflow execution](https://docs.atlan.com/product/connections/self-deployed-runtime/how-tos/configure-workflow-execution): Set up workflow execution with secret retrieval for your Self-deployed Runtime

---

## Install on Kubernetes - Teradata

URL: https://docs.atlan.com/product/connections/self-deployed-runtime/how-tos/install-on-kubernetes
**Connector:** Teradata (database)

> Install an App on Kubernetes using Helm charts, Docker images, and specific configuration

:::info **Did you know?** 
SDR requires additional enablement and licensing. Contact your Atlan representative for details.
:::

:::warning Use the guided install wizard instead
**New Self-Deployed Runtime setups are encouraged to use the [guided install wizard](https://docs.atlan.com/product/connections/self-deployed-runtime/how-tos/install-guided).** It assembles a complete guide tailored to your lifecycle mode, platform, and image procurement on a single page—and it's where new setup options (for example, HTTP proxy and custom CA trust) are documented going forward.

This page is kept for existing users who already reference it and may not include the latest steps.
:::

<h2 id="prerequisites">Prerequisites</h2>

Before you begin, make sure you have:

* `kubectl` installed and configured with administrative access to your target Kubernetes cluster
* Helm version 3.0 or later installed on your deployment machine
* A [Docker Hub Personal Access Token (PAT)](https://start.1password.com/open/i?a=WAVUZSKJO5GMNMVBYWAWECXIUE&v=ouvp3xf5334cxoamyiipzjlewy&i=p76avgzmkkcbftldcuvr5jcof4&h=atlanhq.1password.com) from Atlan
* App-specific helm chart name: `{{deploymentValues.helmChartName}}` 
* Object storage: AWS S3, Google Cloud Storage, or Azure Blob Storage with read/write permissions
* Secret store access: AWS Secret Manager, Azure Key Vault, GCP Secret Manager, HashiCorp Vault, or Kubernetes Secrets with read permissions

:::warning For security reasons, the Docker Hub PAT Token is regenerated on a periodic basis. 
In case the token is embedded in automation scripts or CI/CD pipelines, those jobs may fail. 
Contact your Atlan representative for the latest token.
:::

<h2 id="download-required-files">Download required files</h2>

<h3 id="download-helm-chart">Download Helm chart</h3>

Download the Helm chart for the app:

```bash
helm pull oci://registry-1.docker.io/atlanhq/{{deploymentValues.helmChartName}} --untar
```

This unpacks the chart's `Chart.yaml`, `templates/`, and a default `values.yaml` into `./{{deploymentValues.helmChartName}}/`. You'll replace this default `values.yaml` with your Marketplace copy in the next step.

<h3 id="download-values-yaml">Download values.yaml</h3>

Atlan generates the helm `values.yaml` for your runtime directly from the Marketplace UI, including the OAuth client credentials your runtime uses to authenticate to your tenant.

1. Sign in to your Atlan tenant as an administrator, open **Connector** > **Marketplace**, select the app you want to deploy, and click **Download config for Self-Deployed Runtime** in the right-hand sidebar.

2. In the dialog, keep **New deployment** selected (this mints the OAuth client and full config for a fresh runtime), choose **Kubernetes (Helm)** as the deployment target, and enter a **Deployment name**: a short identifier (lowercase letters, digits, and dashes) that identifies this runtime; the agent in **Workflows > Agent** is named `<app_name>-<deployment_name>`.

3. Click **Generate**. Atlan mints a dedicated OAuth client and produces a `values.yaml` file with:
 - `global.atlanBaseUrl`, `global.clientId`, and `global.clientSecret` already filled in.
 - `image.repository`, `image.tag`, and `name` pinned to the active version for your tenant.
 - `objectstore` and `secretstore` placeholders for you to configure below.

<h3 id="replace-chart-values">Replace chart values.yaml</h3>

Replace the default `values.yaml` inside the unpacked chart with the `values.yaml` you downloaded from the Marketplace.

From this point on, all edits to `values.yaml` must be made inside `./{{deploymentValues.helmChartName}}/`.

<h2 id="modify-values-yaml">Modify values.yaml</h2>

### Object storage

Self-Deployed Runtime needs a store for reading or writing files. Configure the object storage that matches your environment:

:::tip Don't see your preferred object store?
If your preferred object store isn't listed here, [reach out to Atlan support](https://docs.atlan.com/support/submit-request). Support for additional object stores may be available.
:::

<Tabs>
<TabItem value="aws-s3" label="AWS S3" default>

**Required permissions:**

Apply object-level actions to `arn:aws:s3:::BUCKET/*` and the list action to `arn:aws:s3:::BUCKET` in separate IAM statement entries.

| IAM action | Operations covered |
|---|---|
| `s3:GetObject` | GetObject (full and byte-range), HeadObject |
| `s3:PutObject` | PutObject, CreateMultipartUpload, UploadPart, CompleteMultipartUpload |
| `s3:AbortMultipartUpload` | Abort in-flight multipart upload on error (required for streaming write error paths) |
| `s3:DeleteObject` | DeleteObject and DeleteObjects (bulk batch—same IAM action) |
| `s3:ListBucket` | ListObjectsV2—bucket-level permission, not object-level |

```json
{
 "Version": "2012-10-17",
 "Statement": [
 {
 "Effect": "Allow",
 "Action": [
 "s3:GetObject",
 "s3:PutObject",
 "s3:AbortMultipartUpload",
 "s3:DeleteObject"
 ],
 "Resource": "arn:aws:s3:::YOUR-BUCKET/*"
 },
 {
 "Effect": "Allow",
 "Action": "s3:ListBucket",
 "Resource": "arn:aws:s3:::YOUR-BUCKET"
 }
 ]
}
```

**AssumeRole**: when using `assumeRoleArn`, the caller identity additionally needs `sts:AssumeRole` on the target role ARN. The role itself holds the bucket policy described earlier.

**Configure:**

 1. Locate the `objectstore` attribute in `values.yaml`.
 2. Add AWS S3 configuration. For more information, see [AWS S3 Binding Spec](https://docs.dapr.io/reference/components-reference/supported-bindings/s3/).

 ```yaml
 objectstore:
 enabled: true
 spec:
 type: bindings.aws.s3
 version: v1
 metadata:
 - name: accessKey #optional, leave this empty for iam authentication
 value: ""
 - name: secretKey #optional, leave this empty for iam authentication
 value: ""
 - name: bucket #required, name of the bucket where application can write
 value: "<bucket-name>"
 - name: region #required, region of the bucket where application can write
 value: "<bucket-region>"
 - name: forcePathStyle
 value: "true"
 ```

</TabItem>
<TabItem value="gcp-storage" label="Google Cloud Storage">

**Required permissions:**

| IAM permission | Operations covered |
|---|---|
| `storage.objects.get` | GetObject (full and byte-range), object metadata / HeadObject equivalent |
| `storage.objects.create` | PutObject, resumable / streaming write |
| `storage.objects.delete` | DeleteObject (GCS has no native bulk-delete API—`delete_prefix` issues parallel single-object deletes) |
| `storage.objects.list` | ListObjects |

No `storage.buckets.*` permissions are needed. The smallest predefined role that covers all four is **`roles/storage.objectAdmin`** scoped to the bucket. Alternatively, create a custom role with exactly these four permissions.

**Configure:**

 1. Locate the `objectstore` attribute in `values.yaml`.
 2. Add Google Cloud Storage configuration. For more information, see [GCP Storage Bucket binding spec](https://docs.dapr.io/reference/components-reference/supported-bindings/gcpbucket/)

 ```yaml
 objectstore:
 enabled: true
 spec:
 type: bindings.gcp.bucket
 version: v1
 metadata:
 - name: bucket
 value: "your-gcs-bucket-name"
 - name: type
 value: "service_account"
 - name: project_id
 value: "your-gcp-project-id"
 ```

</TabItem>
<TabItem value="azure-blob" label="Azure Blob Storage">

**Required permissions:**

**RBAC**—assign at container or storage-account scope:

| RBAC action | Operations covered |
|---|---|
| `Microsoft.Storage/storageAccounts/blobServices/containers/blobs/read` | GetBlob, GetBlobProperties (HEAD), ListBlobs, byte-range GET |
| `Microsoft.Storage/storageAccounts/blobServices/containers/blobs/write` | PutBlob, PutBlock + PutBlockList (streaming / block write) |
| `Microsoft.Storage/storageAccounts/blobServices/containers/blobs/delete` | DeleteBlob, BlobBatch delete (bulk—up to 256 keys per request) |

The smallest predefined role covering all three is **`Storage Blob Data Contributor`**. `Storage Blob Data Owner` is a superset and is only needed if you additionally require POSIX ACL management on ADLS Gen2.

**SAS token**—minimum permissions at container scope: `r` (read) + `w` (write) + `d` (delete) + `l` (list), that is a container-scoped SAS with **`rwdl`**.

**ADLS Gen2 with POSIX ACLs**: if the storage account has hierarchical namespace enabled and you use ACL-based access control instead of RBAC, the principal needs Execute (`X`) on every parent directory and Read / Write / Delete on the objects in scope. RBAC (`Storage Blob Data Contributor`) is simpler and is recommended unless you have a specific ACL requirement.

**Configure:**

 1. Locate the `objectstore` attribute in `values.yaml`.
 2. Add Azure Blob Storage configuration. For more information, see [Azure Blob Storage binding spec](https://docs.dapr.io/reference/components-reference/supported-bindings/blobstorage/)

 ```yaml
 objectstore:
 enabled: true
 spec:
 type: bindings.azure.blobstorage
 version: v1
 metadata:
 - name: accountName
 value: "your-storage-account-name"
 - name: accountKey
 value: "your-storage-account-key"
 - name: containerName
 value: "your-container-name"
 ```

</TabItem>
</Tabs>

### Secret storage

Self-Deployed Runtime fetches secrets from a secret store to connect to the source systems. The secret store references are used to configure the workflow. Configure the secret store that aligns with your security infrastructure:

:::info Did you know?
Dapr supports additional secret stores which aren't mentioned here. For more information, see [Dapr secret store documentation](https://docs.dapr.io/reference/components-reference/supported-secret-stores/) for other configurations.
:::

:::warning Secret content format and naming
When storing credentials, follow the [secret naming and format requirements](https://docs.atlan.com/product/connections/self-deployed-runtime/how-tos/configure-workflow-execution#secret-content-format).
:::

<Tabs>
<TabItem value="aws-secret-manager" label="AWS Secret Manager" default>
 
 1. Locate the `secretstore` attribute in `values.yaml`.
 2. Add AWS Secret Manager configuration. For more information, see [AWS Secrets Manager](https://docs.dapr.io/reference/components-reference/supported-secret-stores/aws-secret-manager/)

 ```yaml
 secretstore:
 enabled: true
 spec:
 type: secretstores.aws.secretmanager
 version: v1
 metadata:
 - name: region # required, region in which secret is hosted
 value: <secret-region>
 # Needed if IAM authentication is not used
 - name: accessKey
 value: ""
 - name: secretKey
 value: ""
 ```

If you are using IAM role / IRSA authentication, leave `accessKey` and `secretKey` empty.

If you are using an IAM user instead, set:
- `accessKey` to the IAM user's access key ID
- `secretKey` to the IAM user's secret access key

That IAM user must have permission to read the target secret from AWS Secrets Manager:

```json
{
 "Version": "2012-10-17",
 "Statement": [
 {
 "Effect": "Allow",
 "Action": [
 "secretsmanager:GetSecretValue",
 "secretsmanager:DescribeSecret"
 ],
 "Resource": "arn:aws:secretsmanager:<region>:<account-id>:secret:<secret-name>*"
 }
 ]
}
```

:::note
Include the trailing `*` in the secret ARN. AWS appends a random suffix to secret names in the ARN, so omitting it can cause access failures.
:::

</TabItem>
<TabItem value="azure-key-vault" label="Azure Key Vault">

 1. Locate the `secretstore` attribute in `values.yaml`.
 2. Add Azure Key Vault configuration. For more information, see [Azure Key Vault secret store](https://docs.dapr.io/reference/components-reference/supported-secret-stores/azure-keyvault/)

 ```yaml
 secretstore:
 enabled: true
 spec:
 type: secretstores.azure.keyvault
 version: v1
 metadata:
 - name: vaultName
 value: "<your-keyvault-name>"
 - name: azureTenantId
 value: "<your-tenant-id>"
 - name: azureClientId
 value: "<your-client-id>"
 - name: azureClientSecret
 value: "<your-client-secret>"
 - name: azureEnvironment
 value: "AZUREPUBLICCLOUD" # Optional: AZUREPUBLICCLOUD, AZURECHINACLOUD, AZUREUSGOVERNMENTCLOUD, AZUREGERMANCLOUD
 ```
 Azure Key Vault supports multiple authentication methods:
 - **Client Secret**: Use `azureClientSecret` with tenant ID and client ID
 - **Certificate**: Use `azureCertificateFile` instead of client secret
 - **Managed Identity**: Omit authentication fields and use Azure managed identity

 For detailed authentication setup, see the [Authenticating to Azure](https://docs.dapr.io/developing-applications/integrations/azure/azure-authentication/authenticating-azure/) documentation.

</TabItem>
<TabItem value="gcp-secret-manager" label="GCP Secret Manager">

1. Locate the `secretstore` attribute in `values.yaml`.
2. Add Google Cloud Secret Manager configuration. For more information, see [GCP Secret Manager](https://docs.dapr.io/reference/components-reference/supported-secret-stores/gcp-secret-manager/)

 The GCP service account used in this configuration must have the `Secret Manager Secret Accessor` role (`roles/secretmanager.secretAccessor`) on the project where your secrets are stored. The metadata values below come from the service account's JSON key file.

 ```yaml
 secretstore:
 enabled: true
 spec:
 type: secretstores.gcp.secretmanager
 version: v1
 metadata:
 - name: type
 value: "service_account"
 - name: project_id
 value: "<project-id>"
 - name: private_key_id
 value: "<private-key-id>"
 - name: private_key
 value: "<private-key>"
 - name: client_email
 value: "<client-email>"
 - name: client_id
 value: "<client-id>"
 - name: auth_uri
 value: "https://accounts.google.com/o/oauth2/auth"
 - name: token_uri
 value: "https://oauth2.googleapis.com/token"
 - name: auth_provider_x509_cert_url
 value: "https://www.googleapis.com/oauth2/v1/certs"
 - name: client_x509_cert_url
 value: "https://www.googleapis.com/robot/v1/metadata/x509/<client-email>"
 ```

</TabItem>
<TabItem value="hashicorp-vault" label="HashiCorp Vault">

1. Locate the `secretstore` attribute in `values.yaml`.
2. Add HashiCorp Vault configuration. For more information, see [HashiCorp Vault](https://docs.dapr.io/reference/components-reference/supported-secret-stores/hashicorp-vault/)

 ```yaml
 secretstore:
 enabled: true
 spec:
 type: secretstores.hashicorp.vault
 version: v1
 metadata:
 - name: vaultAddr
 value: "[vault_address]" # Optional. Default: "https://127.0.0.1:8200"
 - name: caCert # Optional. This or caPath or caPem
 value: "[ca_cert]"
 - name: caPath # Optional. This or CaCert or caPem
 value: "[path_to_ca_cert_file]"
 - name: caPem # Optional. This or CaCert or CaPath
 value: "[encoded_ca_cert_pem]"
 - name: skipVerify # Optional. Default: false
 value: "[skip_tls_verification]"
 - name: tlsServerName # Optional.
 value: "[tls_config_server_name]"
 - name: vaultTokenMountPath # Required if vaultToken not provided. Path to token file.
 value: "[path_to_file_containing_token]"
 - name: vaultToken # Required if vaultTokenMountPath not provided. Token value.
 value: "[vault_token]"
 - name: vaultKVPrefix # Optional. Default: "dapr"
 value: "[vault_prefix]"
 - name: vaultKVUsePrefix # Optional. default: "true"
 value: "[true/false]"
 - name: enginePath # Optional. default: "secret"
 value: "secret"
 - name: vaultValueType # Optional. default: "map"
 value: "map"
 ```

</TabItem>
<TabItem value="kubernetes-secrets" label="Kubernetes Secrets">

1. Locate the `secretstore` attribute in `values.yaml`.
2. Add Kubernetes native secret storage. For more information, see [Kubernetes secrets](https://docs.dapr.io/reference/components-reference/supported-secret-stores/kubernetes-secret-store/)

 ```yaml
 secretstore:
 enabled: true
 spec:
 type: secretstores.kubernetes
 version: v1
 metadata:
 - name: defaultNamespace
 value: "default" # Optional: Default namespace to retrieve secrets from
 - name: kubeconfigPath
 value: "/path/to/kubeconfig" # Optional: Path to kubeconfig file
 ```
 When Dapr is deployed to a Kubernetes cluster, a secret store with the name `kubernetes` is automatically provisioned. You can use this native Kubernetes secret store with no need to create, deploy or maintain a component configuration file.

</TabItem>
<TabItem value="environment-variable-based" label="Environment Variables">

1. Locate the `secretstore` attribute in `values.yaml`.
2. Add Local environment variables as the spec. For more information, see [Local Environment Variables](https://docs.dapr.io/reference/components-reference/supported-secret-stores/envvar-secret-store/)

 ```yaml
 secretstore:
 enabled: true
 spec:
 type: secretstores.local.env
 version: v1
 ```

</TabItem>
</Tabs>

### Image source

Choose how the cluster pulls the app image. Most installs use Atlan's Docker Hub directly; mirror to a private registry if your organization requires it.

<Tabs>
<TabItem value="docker-hub" label="Public Docker Hub" default>

The chart pulls the app image from Atlan's Docker Hub at runtime. The pod needs a Kubernetes secret containing your Docker Hub PAT to authenticate:

```bash
kubectl create secret docker-registry atlan-docker-secret \
 --docker-server=docker.io \
 --docker-username=YOUR_USERNAME \
 --docker-password=YOUR_PAT_TOKEN \
 -n <namespace>
```

- Replace `YOUR_USERNAME` with the Docker Hub username provided by Atlan.
- Replace `YOUR_PAT_TOKEN` with the Personal Access Token (PAT) provided by Atlan.
- Replace `<namespace>` with the namespace you need to install the chart into. The secret and the release must live in the same namespace, or the pod fails with `ImagePullBackOff`.

The downloaded `values.yaml` already references this secret under `imagePullSecrets`. If you use a different secret name, update that field in the file.

</TabItem>
<TabItem value="private-registry" label="Private image repo">

Mirror the Atlan image to your enterprise registry and update `values.yaml` to point at it.

1. Authenticate with Docker Hub using the PAT from Atlan, then pull the source image. The image and tag come from `image.repository` and `image.tag` in the downloaded `values.yaml`:

 ```bash
 docker login -u atlanhq
 # When prompted for password, enter the PAT provided by Atlan
 docker pull <image.repository>:<image.tag>
 ```

2. Push the image to your enterprise's registry. Note down the new repository name and image tag.

3. Update `image.repository` and `image.tag` in `values.yaml` with the new values.

4. If your private registry requires authentication, create an image-pull secret in the target namespace and set `imagePullSecrets` in `values.yaml` to its name.

</TabItem>
</Tabs>

<h2 id="deploy-app">Deploy app</h2>

Follow these steps to deploy the secure app:

* Install the helm chart. The chart directory now carries your edited `values.yaml`, so no `-f` flag is needed:

 ```bash
 helm install {{deploymentValues.helmChartName}}-release ./{{deploymentValues.helmChartName}} -n <namespace>
 ```

 - Replace `<namespace>` with your target Kubernetes namespace.
 - The helm chart name `{{deploymentValues.helmChartName}}` is automatically used from your selected app.

The deployment process typically takes a few minutes to complete depending on factors like Kubernetes cluster resource availability, private image repository download time etc.

<h2 id="verify-app">Verify app</h2>

Follow these steps to verify deployment:

### Verify deployment status on cluster

1. Check pod status:

 ```bash
 kubectl get pods -n <namespace>
 ```

 The output appears similar to:

 ```
 NAME READY STATUS RESTARTS AGE
 <helm-chart-name>-release-<helm-chart-name>-5dff95cd85-cvk5z 1/1 Running 0 2m
 ```
 
 Replace `<helm-chart-name>` with your app's helm chart name (shown in the prerequisites section earlier in this guide).

 The pod status shows `Running` with `1/1` ready containers.

2. Verify logs for the running pod
 
 ```bash
 kubectl logs -n <namespace> -l app.kubernetes.io/name={{deploymentValues.helmChartName}} --tail=50 -f
 ```
 **Example application logs**: Look for these key log messages that confirm successful deployment:

 * `Uvicorn running on http://0.0.0.0:8000` - Web server started
 * `Workflow engine initialized` - Workflow processing ready
 * `dapr initialized. Status: Running` - Dapr runtime active
 * `Starting worker with task queue: atlan-<package-name>-DEPLOYMENT_NAME` - Worker process started (replace `<package-name>` with your app's package name)
 * `GET /server/ready 200` - Health check endpoint responding

### Verify registration via Atlan UI

Once the App is successfully deployed, it communicates to the Atlan tenant and registers itself. Verify App registration is successful in Atlan:

1. In the same Atlan tenant, navigate to **Workflows** > **Agent**.
2. Look for an entry named `<app_name>-<deployment_name>`, where `<app_name>` matches your selected app (for example, "Oracle" or "Microsoft SQL Server") and `<deployment_name>` is the deployment name you entered when generating the config.
3. Confirm the agent status displays as **Active**.

Agent registration and status takes a couple of minutes to reflect in the Atlan UI.

<h2 id="next-steps">Next steps</h2>

* [Configure workflow execution](https://docs.atlan.com/product/connections/self-deployed-runtime/how-tos/configure-workflow-execution): Set up workflow execution with secret retrieval for your Self-deployed Runtime

---

## Install on Kubernetes - Trino

URL: https://docs.atlan.com/product/connections/self-deployed-runtime/how-tos/install-on-kubernetes
**Connector:** Trino (database)

> Install an App on Kubernetes using Helm charts, Docker images, and specific configuration

:::info **Did you know?** 
SDR requires additional enablement and licensing. Contact your Atlan representative for details.
:::

:::warning Use the guided install wizard instead
**New Self-Deployed Runtime setups are encouraged to use the [guided install wizard](https://docs.atlan.com/product/connections/self-deployed-runtime/how-tos/install-guided).** It assembles a complete guide tailored to your lifecycle mode, platform, and image procurement on a single page—and it's where new setup options (for example, HTTP proxy and custom CA trust) are documented going forward.

This page is kept for existing users who already reference it and may not include the latest steps.
:::

<h2 id="prerequisites">Prerequisites</h2>

Before you begin, make sure you have:

* `kubectl` installed and configured with administrative access to your target Kubernetes cluster
* Helm version 3.0 or later installed on your deployment machine
* A [Docker Hub Personal Access Token (PAT)](https://start.1password.com/open/i?a=WAVUZSKJO5GMNMVBYWAWECXIUE&v=ouvp3xf5334cxoamyiipzjlewy&i=p76avgzmkkcbftldcuvr5jcof4&h=atlanhq.1password.com) from Atlan
* App-specific helm chart name: `{{deploymentValues.helmChartName}}` 
* Object storage: AWS S3, Google Cloud Storage, or Azure Blob Storage with read/write permissions
* Secret store access: AWS Secret Manager, Azure Key Vault, GCP Secret Manager, HashiCorp Vault, or Kubernetes Secrets with read permissions

:::warning For security reasons, the Docker Hub PAT Token is regenerated on a periodic basis. 
In case the token is embedded in automation scripts or CI/CD pipelines, those jobs may fail. 
Contact your Atlan representative for the latest token.
:::

<h2 id="download-required-files">Download required files</h2>

<h3 id="download-helm-chart">Download Helm chart</h3>

Download the Helm chart for the app:

```bash
helm pull oci://registry-1.docker.io/atlanhq/{{deploymentValues.helmChartName}} --untar
```

This unpacks the chart's `Chart.yaml`, `templates/`, and a default `values.yaml` into `./{{deploymentValues.helmChartName}}/`. You'll replace this default `values.yaml` with your Marketplace copy in the next step.

<h3 id="download-values-yaml">Download values.yaml</h3>

Atlan generates the helm `values.yaml` for your runtime directly from the Marketplace UI, including the OAuth client credentials your runtime uses to authenticate to your tenant.

1. Sign in to your Atlan tenant as an administrator, open **Connector** > **Marketplace**, select the app you want to deploy, and click **Download config for Self-Deployed Runtime** in the right-hand sidebar.

2. In the dialog, keep **New deployment** selected (this mints the OAuth client and full config for a fresh runtime), choose **Kubernetes (Helm)** as the deployment target, and enter a **Deployment name**: a short identifier (lowercase letters, digits, and dashes) that identifies this runtime; the agent in **Workflows > Agent** is named `<app_name>-<deployment_name>`.

3. Click **Generate**. Atlan mints a dedicated OAuth client and produces a `values.yaml` file with:
 - `global.atlanBaseUrl`, `global.clientId`, and `global.clientSecret` already filled in.
 - `image.repository`, `image.tag`, and `name` pinned to the active version for your tenant.
 - `objectstore` and `secretstore` placeholders for you to configure below.

<h3 id="replace-chart-values">Replace chart values.yaml</h3>

Replace the default `values.yaml` inside the unpacked chart with the `values.yaml` you downloaded from the Marketplace.

From this point on, all edits to `values.yaml` must be made inside `./{{deploymentValues.helmChartName}}/`.

<h2 id="modify-values-yaml">Modify values.yaml</h2>

### Object storage

Self-Deployed Runtime needs a store for reading or writing files. Configure the object storage that matches your environment:

:::tip Don't see your preferred object store?
If your preferred object store isn't listed here, [reach out to Atlan support](https://docs.atlan.com/support/submit-request). Support for additional object stores may be available.
:::

<Tabs>
<TabItem value="aws-s3" label="AWS S3" default>

**Required permissions:**

Apply object-level actions to `arn:aws:s3:::BUCKET/*` and the list action to `arn:aws:s3:::BUCKET` in separate IAM statement entries.

| IAM action | Operations covered |
|---|---|
| `s3:GetObject` | GetObject (full and byte-range), HeadObject |
| `s3:PutObject` | PutObject, CreateMultipartUpload, UploadPart, CompleteMultipartUpload |
| `s3:AbortMultipartUpload` | Abort in-flight multipart upload on error (required for streaming write error paths) |
| `s3:DeleteObject` | DeleteObject and DeleteObjects (bulk batch—same IAM action) |
| `s3:ListBucket` | ListObjectsV2—bucket-level permission, not object-level |

```json
{
 "Version": "2012-10-17",
 "Statement": [
 {
 "Effect": "Allow",
 "Action": [
 "s3:GetObject",
 "s3:PutObject",
 "s3:AbortMultipartUpload",
 "s3:DeleteObject"
 ],
 "Resource": "arn:aws:s3:::YOUR-BUCKET/*"
 },
 {
 "Effect": "Allow",
 "Action": "s3:ListBucket",
 "Resource": "arn:aws:s3:::YOUR-BUCKET"
 }
 ]
}
```

**AssumeRole**: when using `assumeRoleArn`, the caller identity additionally needs `sts:AssumeRole` on the target role ARN. The role itself holds the bucket policy described earlier.

**Configure:**

 1. Locate the `objectstore` attribute in `values.yaml`.
 2. Add AWS S3 configuration. For more information, see [AWS S3 Binding Spec](https://docs.dapr.io/reference/components-reference/supported-bindings/s3/).

 ```yaml
 objectstore:
 enabled: true
 spec:
 type: bindings.aws.s3
 version: v1
 metadata:
 - name: accessKey #optional, leave this empty for iam authentication
 value: ""
 - name: secretKey #optional, leave this empty for iam authentication
 value: ""
 - name: bucket #required, name of the bucket where application can write
 value: "<bucket-name>"
 - name: region #required, region of the bucket where application can write
 value: "<bucket-region>"
 - name: forcePathStyle
 value: "true"
 ```

</TabItem>
<TabItem value="gcp-storage" label="Google Cloud Storage">

**Required permissions:**

| IAM permission | Operations covered |
|---|---|
| `storage.objects.get` | GetObject (full and byte-range), object metadata / HeadObject equivalent |
| `storage.objects.create` | PutObject, resumable / streaming write |
| `storage.objects.delete` | DeleteObject (GCS has no native bulk-delete API—`delete_prefix` issues parallel single-object deletes) |
| `storage.objects.list` | ListObjects |

No `storage.buckets.*` permissions are needed. The smallest predefined role that covers all four is **`roles/storage.objectAdmin`** scoped to the bucket. Alternatively, create a custom role with exactly these four permissions.

**Configure:**

 1. Locate the `objectstore` attribute in `values.yaml`.
 2. Add Google Cloud Storage configuration. For more information, see [GCP Storage Bucket binding spec](https://docs.dapr.io/reference/components-reference/supported-bindings/gcpbucket/)

 ```yaml
 objectstore:
 enabled: true
 spec:
 type: bindings.gcp.bucket
 version: v1
 metadata:
 - name: bucket
 value: "your-gcs-bucket-name"
 - name: type
 value: "service_account"
 - name: project_id
 value: "your-gcp-project-id"
 ```

</TabItem>
<TabItem value="azure-blob" label="Azure Blob Storage">

**Required permissions:**

**RBAC**—assign at container or storage-account scope:

| RBAC action | Operations covered |
|---|---|
| `Microsoft.Storage/storageAccounts/blobServices/containers/blobs/read` | GetBlob, GetBlobProperties (HEAD), ListBlobs, byte-range GET |
| `Microsoft.Storage/storageAccounts/blobServices/containers/blobs/write` | PutBlob, PutBlock + PutBlockList (streaming / block write) |
| `Microsoft.Storage/storageAccounts/blobServices/containers/blobs/delete` | DeleteBlob, BlobBatch delete (bulk—up to 256 keys per request) |

The smallest predefined role covering all three is **`Storage Blob Data Contributor`**. `Storage Blob Data Owner` is a superset and is only needed if you additionally require POSIX ACL management on ADLS Gen2.

**SAS token**—minimum permissions at container scope: `r` (read) + `w` (write) + `d` (delete) + `l` (list), that is a container-scoped SAS with **`rwdl`**.

**ADLS Gen2 with POSIX ACLs**: if the storage account has hierarchical namespace enabled and you use ACL-based access control instead of RBAC, the principal needs Execute (`X`) on every parent directory and Read / Write / Delete on the objects in scope. RBAC (`Storage Blob Data Contributor`) is simpler and is recommended unless you have a specific ACL requirement.

**Configure:**

 1. Locate the `objectstore` attribute in `values.yaml`.
 2. Add Azure Blob Storage configuration. For more information, see [Azure Blob Storage binding spec](https://docs.dapr.io/reference/components-reference/supported-bindings/blobstorage/)

 ```yaml
 objectstore:
 enabled: true
 spec:
 type: bindings.azure.blobstorage
 version: v1
 metadata:
 - name: accountName
 value: "your-storage-account-name"
 - name: accountKey
 value: "your-storage-account-key"
 - name: containerName
 value: "your-container-name"
 ```

</TabItem>
</Tabs>

### Secret storage

Self-Deployed Runtime fetches secrets from a secret store to connect to the source systems. The secret store references are used to configure the workflow. Configure the secret store that aligns with your security infrastructure:

:::info Did you know?
Dapr supports additional secret stores which aren't mentioned here. For more information, see [Dapr secret store documentation](https://docs.dapr.io/reference/components-reference/supported-secret-stores/) for other configurations.
:::

:::warning Secret content format and naming
When storing credentials, follow the [secret naming and format requirements](https://docs.atlan.com/product/connections/self-deployed-runtime/how-tos/configure-workflow-execution#secret-content-format).
:::

<Tabs>
<TabItem value="aws-secret-manager" label="AWS Secret Manager" default>
 
 1. Locate the `secretstore` attribute in `values.yaml`.
 2. Add AWS Secret Manager configuration. For more information, see [AWS Secrets Manager](https://docs.dapr.io/reference/components-reference/supported-secret-stores/aws-secret-manager/)

 ```yaml
 secretstore:
 enabled: true
 spec:
 type: secretstores.aws.secretmanager
 version: v1
 metadata:
 - name: region # required, region in which secret is hosted
 value: <secret-region>
 # Needed if IAM authentication is not used
 - name: accessKey
 value: ""
 - name: secretKey
 value: ""
 ```

If you are using IAM role / IRSA authentication, leave `accessKey` and `secretKey` empty.

If you are using an IAM user instead, set:
- `accessKey` to the IAM user's access key ID
- `secretKey` to the IAM user's secret access key

That IAM user must have permission to read the target secret from AWS Secrets Manager:

```json
{
 "Version": "2012-10-17",
 "Statement": [
 {
 "Effect": "Allow",
 "Action": [
 "secretsmanager:GetSecretValue",
 "secretsmanager:DescribeSecret"
 ],
 "Resource": "arn:aws:secretsmanager:<region>:<account-id>:secret:<secret-name>*"
 }
 ]
}
```

:::note
Include the trailing `*` in the secret ARN. AWS appends a random suffix to secret names in the ARN, so omitting it can cause access failures.
:::

</TabItem>
<TabItem value="azure-key-vault" label="Azure Key Vault">

 1. Locate the `secretstore` attribute in `values.yaml`.
 2. Add Azure Key Vault configuration. For more information, see [Azure Key Vault secret store](https://docs.dapr.io/reference/components-reference/supported-secret-stores/azure-keyvault/)

 ```yaml
 secretstore:
 enabled: true
 spec:
 type: secretstores.azure.keyvault
 version: v1
 metadata:
 - name: vaultName
 value: "<your-keyvault-name>"
 - name: azureTenantId
 value: "<your-tenant-id>"
 - name: azureClientId
 value: "<your-client-id>"
 - name: azureClientSecret
 value: "<your-client-secret>"
 - name: azureEnvironment
 value: "AZUREPUBLICCLOUD" # Optional: AZUREPUBLICCLOUD, AZURECHINACLOUD, AZUREUSGOVERNMENTCLOUD, AZUREGERMANCLOUD
 ```
 Azure Key Vault supports multiple authentication methods:
 - **Client Secret**: Use `azureClientSecret` with tenant ID and client ID
 - **Certificate**: Use `azureCertificateFile` instead of client secret
 - **Managed Identity**: Omit authentication fields and use Azure managed identity

 For detailed authentication setup, see the [Authenticating to Azure](https://docs.dapr.io/developing-applications/integrations/azure/azure-authentication/authenticating-azure/) documentation.

</TabItem>
<TabItem value="gcp-secret-manager" label="GCP Secret Manager">

1. Locate the `secretstore` attribute in `values.yaml`.
2. Add Google Cloud Secret Manager configuration. For more information, see [GCP Secret Manager](https://docs.dapr.io/reference/components-reference/supported-secret-stores/gcp-secret-manager/)

 The GCP service account used in this configuration must have the `Secret Manager Secret Accessor` role (`roles/secretmanager.secretAccessor`) on the project where your secrets are stored. The metadata values below come from the service account's JSON key file.

 ```yaml
 secretstore:
 enabled: true
 spec:
 type: secretstores.gcp.secretmanager
 version: v1
 metadata:
 - name: type
 value: "service_account"
 - name: project_id
 value: "<project-id>"
 - name: private_key_id
 value: "<private-key-id>"
 - name: private_key
 value: "<private-key>"
 - name: client_email
 value: "<client-email>"
 - name: client_id
 value: "<client-id>"
 - name: auth_uri
 value: "https://accounts.google.com/o/oauth2/auth"
 - name: token_uri
 value: "https://oauth2.googleapis.com/token"
 - name: auth_provider_x509_cert_url
 value: "https://www.googleapis.com/oauth2/v1/certs"
 - name: client_x509_cert_url
 value: "https://www.googleapis.com/robot/v1/metadata/x509/<client-email>"
 ```

</TabItem>
<TabItem value="hashicorp-vault" label="HashiCorp Vault">

1. Locate the `secretstore` attribute in `values.yaml`.
2. Add HashiCorp Vault configuration. For more information, see [HashiCorp Vault](https://docs.dapr.io/reference/components-reference/supported-secret-stores/hashicorp-vault/)

 ```yaml
 secretstore:
 enabled: true
 spec:
 type: secretstores.hashicorp.vault
 version: v1
 metadata:
 - name: vaultAddr
 value: "[vault_address]" # Optional. Default: "https://127.0.0.1:8200"
 - name: caCert # Optional. This or caPath or caPem
 value: "[ca_cert]"
 - name: caPath # Optional. This or CaCert or caPem
 value: "[path_to_ca_cert_file]"
 - name: caPem # Optional. This or CaCert or CaPath
 value: "[encoded_ca_cert_pem]"
 - name: skipVerify # Optional. Default: false
 value: "[skip_tls_verification]"
 - name: tlsServerName # Optional.
 value: "[tls_config_server_name]"
 - name: vaultTokenMountPath # Required if vaultToken not provided. Path to token file.
 value: "[path_to_file_containing_token]"
 - name: vaultToken # Required if vaultTokenMountPath not provided. Token value.
 value: "[vault_token]"
 - name: vaultKVPrefix # Optional. Default: "dapr"
 value: "[vault_prefix]"
 - name: vaultKVUsePrefix # Optional. default: "true"
 value: "[true/false]"
 - name: enginePath # Optional. default: "secret"
 value: "secret"
 - name: vaultValueType # Optional. default: "map"
 value: "map"
 ```

</TabItem>
<TabItem value="kubernetes-secrets" label="Kubernetes Secrets">

1. Locate the `secretstore` attribute in `values.yaml`.
2. Add Kubernetes native secret storage. For more information, see [Kubernetes secrets](https://docs.dapr.io/reference/components-reference/supported-secret-stores/kubernetes-secret-store/)

 ```yaml
 secretstore:
 enabled: true
 spec:
 type: secretstores.kubernetes
 version: v1
 metadata:
 - name: defaultNamespace
 value: "default" # Optional: Default namespace to retrieve secrets from
 - name: kubeconfigPath
 value: "/path/to/kubeconfig" # Optional: Path to kubeconfig file
 ```
 When Dapr is deployed to a Kubernetes cluster, a secret store with the name `kubernetes` is automatically provisioned. You can use this native Kubernetes secret store with no need to create, deploy or maintain a component configuration file.

</TabItem>
<TabItem value="environment-variable-based" label="Environment Variables">

1. Locate the `secretstore` attribute in `values.yaml`.
2. Add Local environment variables as the spec. For more information, see [Local Environment Variables](https://docs.dapr.io/reference/components-reference/supported-secret-stores/envvar-secret-store/)

 ```yaml
 secretstore:
 enabled: true
 spec:
 type: secretstores.local.env
 version: v1
 ```

</TabItem>
</Tabs>

### Image source

Choose how the cluster pulls the app image. Most installs use Atlan's Docker Hub directly; mirror to a private registry if your organization requires it.

<Tabs>
<TabItem value="docker-hub" label="Public Docker Hub" default>

The chart pulls the app image from Atlan's Docker Hub at runtime. The pod needs a Kubernetes secret containing your Docker Hub PAT to authenticate:

```bash
kubectl create secret docker-registry atlan-docker-secret \
 --docker-server=docker.io \
 --docker-username=YOUR_USERNAME \
 --docker-password=YOUR_PAT_TOKEN \
 -n <namespace>
```

- Replace `YOUR_USERNAME` with the Docker Hub username provided by Atlan.
- Replace `YOUR_PAT_TOKEN` with the Personal Access Token (PAT) provided by Atlan.
- Replace `<namespace>` with the namespace you need to install the chart into. The secret and the release must live in the same namespace, or the pod fails with `ImagePullBackOff`.

The downloaded `values.yaml` already references this secret under `imagePullSecrets`. If you use a different secret name, update that field in the file.

</TabItem>
<TabItem value="private-registry" label="Private image repo">

Mirror the Atlan image to your enterprise registry and update `values.yaml` to point at it.

1. Authenticate with Docker Hub using the PAT from Atlan, then pull the source image. The image and tag come from `image.repository` and `image.tag` in the downloaded `values.yaml`:

 ```bash
 docker login -u atlanhq
 # When prompted for password, enter the PAT provided by Atlan
 docker pull <image.repository>:<image.tag>
 ```

2. Push the image to your enterprise's registry. Note down the new repository name and image tag.

3. Update `image.repository` and `image.tag` in `values.yaml` with the new values.

4. If your private registry requires authentication, create an image-pull secret in the target namespace and set `imagePullSecrets` in `values.yaml` to its name.

</TabItem>
</Tabs>

<h2 id="deploy-app">Deploy app</h2>

Follow these steps to deploy the secure app:

* Install the helm chart. The chart directory now carries your edited `values.yaml`, so no `-f` flag is needed:

 ```bash
 helm install {{deploymentValues.helmChartName}}-release ./{{deploymentValues.helmChartName}} -n <namespace>
 ```

 - Replace `<namespace>` with your target Kubernetes namespace.
 - The helm chart name `{{deploymentValues.helmChartName}}` is automatically used from your selected app.

The deployment process typically takes a few minutes to complete depending on factors like Kubernetes cluster resource availability, private image repository download time etc.

<h2 id="verify-app">Verify app</h2>

Follow these steps to verify deployment:

### Verify deployment status on cluster

1. Check pod status:

 ```bash
 kubectl get pods -n <namespace>
 ```

 The output appears similar to:

 ```
 NAME READY STATUS RESTARTS AGE
 <helm-chart-name>-release-<helm-chart-name>-5dff95cd85-cvk5z 1/1 Running 0 2m
 ```
 
 Replace `<helm-chart-name>` with your app's helm chart name (shown in the prerequisites section earlier in this guide).

 The pod status shows `Running` with `1/1` ready containers.

2. Verify logs for the running pod
 
 ```bash
 kubectl logs -n <namespace> -l app.kubernetes.io/name={{deploymentValues.helmChartName}} --tail=50 -f
 ```
 **Example application logs**: Look for these key log messages that confirm successful deployment:

 * `Uvicorn running on http://0.0.0.0:8000` - Web server started
 * `Workflow engine initialized` - Workflow processing ready
 * `dapr initialized. Status: Running` - Dapr runtime active
 * `Starting worker with task queue: atlan-<package-name>-DEPLOYMENT_NAME` - Worker process started (replace `<package-name>` with your app's package name)
 * `GET /server/ready 200` - Health check endpoint responding

### Verify registration via Atlan UI

Once the App is successfully deployed, it communicates to the Atlan tenant and registers itself. Verify App registration is successful in Atlan:

1. In the same Atlan tenant, navigate to **Workflows** > **Agent**.
2. Look for an entry named `<app_name>-<deployment_name>`, where `<app_name>` matches your selected app (for example, "Oracle" or "Microsoft SQL Server") and `<deployment_name>` is the deployment name you entered when generating the config.
3. Confirm the agent status displays as **Active**.

Agent registration and status takes a couple of minutes to reflect in the Atlan UI.

<h2 id="next-steps">Next steps</h2>

* [Configure workflow execution](https://docs.atlan.com/product/connections/self-deployed-runtime/how-tos/configure-workflow-execution): Set up workflow execution with secret retrieval for your Self-deployed Runtime

---

## Install on Kubernetes - SAP BW/4HANA

URL: https://docs.atlan.com/product/connections/self-deployed-runtime/how-tos/install-on-kubernetes
**Connector:** SAP BW/4HANA (erp)

> Install an App on Kubernetes using Helm charts, Docker images, and specific configuration

:::info **Did you know?** 
SDR requires additional enablement and licensing. Contact your Atlan representative for details.
:::

:::warning Use the guided install wizard instead
**New Self-Deployed Runtime setups are encouraged to use the [guided install wizard](https://docs.atlan.com/product/connections/self-deployed-runtime/how-tos/install-guided).** It assembles a complete guide tailored to your lifecycle mode, platform, and image procurement on a single page—and it's where new setup options (for example, HTTP proxy and custom CA trust) are documented going forward.

This page is kept for existing users who already reference it and may not include the latest steps.
:::

<h2 id="prerequisites">Prerequisites</h2>

Before you begin, make sure you have:

* `kubectl` installed and configured with administrative access to your target Kubernetes cluster
* Helm version 3.0 or later installed on your deployment machine
* A [Docker Hub Personal Access Token (PAT)](https://start.1password.com/open/i?a=WAVUZSKJO5GMNMVBYWAWECXIUE&v=ouvp3xf5334cxoamyiipzjlewy&i=p76avgzmkkcbftldcuvr5jcof4&h=atlanhq.1password.com) from Atlan
* App-specific helm chart name: `{{deploymentValues.helmChartName}}` 
* Object storage: AWS S3, Google Cloud Storage, or Azure Blob Storage with read/write permissions
* Secret store access: AWS Secret Manager, Azure Key Vault, GCP Secret Manager, HashiCorp Vault, or Kubernetes Secrets with read permissions

:::warning For security reasons, the Docker Hub PAT Token is regenerated on a periodic basis. 
In case the token is embedded in automation scripts or CI/CD pipelines, those jobs may fail. 
Contact your Atlan representative for the latest token.
:::

<h2 id="download-required-files">Download required files</h2>

<h3 id="download-helm-chart">Download Helm chart</h3>

Download the Helm chart for the app:

```bash
helm pull oci://registry-1.docker.io/atlanhq/{{deploymentValues.helmChartName}} --untar
```

This unpacks the chart's `Chart.yaml`, `templates/`, and a default `values.yaml` into `./{{deploymentValues.helmChartName}}/`. You'll replace this default `values.yaml` with your Marketplace copy in the next step.

<h3 id="download-values-yaml">Download values.yaml</h3>

Atlan generates the helm `values.yaml` for your runtime directly from the Marketplace UI, including the OAuth client credentials your runtime uses to authenticate to your tenant.

1. Sign in to your Atlan tenant as an administrator, open **Connector** > **Marketplace**, select the app you want to deploy, and click **Download config for Self-Deployed Runtime** in the right-hand sidebar.

2. In the dialog, keep **New deployment** selected (this mints the OAuth client and full config for a fresh runtime), choose **Kubernetes (Helm)** as the deployment target, and enter a **Deployment name**: a short identifier (lowercase letters, digits, and dashes) that identifies this runtime; the agent in **Workflows > Agent** is named `<app_name>-<deployment_name>`.

3. Click **Generate**. Atlan mints a dedicated OAuth client and produces a `values.yaml` file with:
 - `global.atlanBaseUrl`, `global.clientId`, and `global.clientSecret` already filled in.
 - `image.repository`, `image.tag`, and `name` pinned to the active version for your tenant.
 - `objectstore` and `secretstore` placeholders for you to configure below.

<h3 id="replace-chart-values">Replace chart values.yaml</h3>

Replace the default `values.yaml` inside the unpacked chart with the `values.yaml` you downloaded from the Marketplace.

From this point on, all edits to `values.yaml` must be made inside `./{{deploymentValues.helmChartName}}/`.

<h2 id="modify-values-yaml">Modify values.yaml</h2>

### Object storage

Self-Deployed Runtime needs a store for reading or writing files. Configure the object storage that matches your environment:

:::tip Don't see your preferred object store?
If your preferred object store isn't listed here, [reach out to Atlan support](https://docs.atlan.com/support/submit-request). Support for additional object stores may be available.
:::

<Tabs>
<TabItem value="aws-s3" label="AWS S3" default>

**Required permissions:**

Apply object-level actions to `arn:aws:s3:::BUCKET/*` and the list action to `arn:aws:s3:::BUCKET` in separate IAM statement entries.

| IAM action | Operations covered |
|---|---|
| `s3:GetObject` | GetObject (full and byte-range), HeadObject |
| `s3:PutObject` | PutObject, CreateMultipartUpload, UploadPart, CompleteMultipartUpload |
| `s3:AbortMultipartUpload` | Abort in-flight multipart upload on error (required for streaming write error paths) |
| `s3:DeleteObject` | DeleteObject and DeleteObjects (bulk batch—same IAM action) |
| `s3:ListBucket` | ListObjectsV2—bucket-level permission, not object-level |

```json
{
 "Version": "2012-10-17",
 "Statement": [
 {
 "Effect": "Allow",
 "Action": [
 "s3:GetObject",
 "s3:PutObject",
 "s3:AbortMultipartUpload",
 "s3:DeleteObject"
 ],
 "Resource": "arn:aws:s3:::YOUR-BUCKET/*"
 },
 {
 "Effect": "Allow",
 "Action": "s3:ListBucket",
 "Resource": "arn:aws:s3:::YOUR-BUCKET"
 }
 ]
}
```

**AssumeRole**: when using `assumeRoleArn`, the caller identity additionally needs `sts:AssumeRole` on the target role ARN. The role itself holds the bucket policy described earlier.

**Configure:**

 1. Locate the `objectstore` attribute in `values.yaml`.
 2. Add AWS S3 configuration. For more information, see [AWS S3 Binding Spec](https://docs.dapr.io/reference/components-reference/supported-bindings/s3/).

 ```yaml
 objectstore:
 enabled: true
 spec:
 type: bindings.aws.s3
 version: v1
 metadata:
 - name: accessKey #optional, leave this empty for iam authentication
 value: ""
 - name: secretKey #optional, leave this empty for iam authentication
 value: ""
 - name: bucket #required, name of the bucket where application can write
 value: "<bucket-name>"
 - name: region #required, region of the bucket where application can write
 value: "<bucket-region>"
 - name: forcePathStyle
 value: "true"
 ```

</TabItem>
<TabItem value="gcp-storage" label="Google Cloud Storage">

**Required permissions:**

| IAM permission | Operations covered |
|---|---|
| `storage.objects.get` | GetObject (full and byte-range), object metadata / HeadObject equivalent |
| `storage.objects.create` | PutObject, resumable / streaming write |
| `storage.objects.delete` | DeleteObject (GCS has no native bulk-delete API—`delete_prefix` issues parallel single-object deletes) |
| `storage.objects.list` | ListObjects |

No `storage.buckets.*` permissions are needed. The smallest predefined role that covers all four is **`roles/storage.objectAdmin`** scoped to the bucket. Alternatively, create a custom role with exactly these four permissions.

**Configure:**

 1. Locate the `objectstore` attribute in `values.yaml`.
 2. Add Google Cloud Storage configuration. For more information, see [GCP Storage Bucket binding spec](https://docs.dapr.io/reference/components-reference/supported-bindings/gcpbucket/)

 ```yaml
 objectstore:
 enabled: true
 spec:
 type: bindings.gcp.bucket
 version: v1
 metadata:
 - name: bucket
 value: "your-gcs-bucket-name"
 - name: type
 value: "service_account"
 - name: project_id
 value: "your-gcp-project-id"
 ```

</TabItem>
<TabItem value="azure-blob" label="Azure Blob Storage">

**Required permissions:**

**RBAC**—assign at container or storage-account scope:

| RBAC action | Operations covered |
|---|---|
| `Microsoft.Storage/storageAccounts/blobServices/containers/blobs/read` | GetBlob, GetBlobProperties (HEAD), ListBlobs, byte-range GET |
| `Microsoft.Storage/storageAccounts/blobServices/containers/blobs/write` | PutBlob, PutBlock + PutBlockList (streaming / block write) |
| `Microsoft.Storage/storageAccounts/blobServices/containers/blobs/delete` | DeleteBlob, BlobBatch delete (bulk—up to 256 keys per request) |

The smallest predefined role covering all three is **`Storage Blob Data Contributor`**. `Storage Blob Data Owner` is a superset and is only needed if you additionally require POSIX ACL management on ADLS Gen2.

**SAS token**—minimum permissions at container scope: `r` (read) + `w` (write) + `d` (delete) + `l` (list), that is a container-scoped SAS with **`rwdl`**.

**ADLS Gen2 with POSIX ACLs**: if the storage account has hierarchical namespace enabled and you use ACL-based access control instead of RBAC, the principal needs Execute (`X`) on every parent directory and Read / Write / Delete on the objects in scope. RBAC (`Storage Blob Data Contributor`) is simpler and is recommended unless you have a specific ACL requirement.

**Configure:**

 1. Locate the `objectstore` attribute in `values.yaml`.
 2. Add Azure Blob Storage configuration. For more information, see [Azure Blob Storage binding spec](https://docs.dapr.io/reference/components-reference/supported-bindings/blobstorage/)

 ```yaml
 objectstore:
 enabled: true
 spec:
 type: bindings.azure.blobstorage
 version: v1
 metadata:
 - name: accountName
 value: "your-storage-account-name"
 - name: accountKey
 value: "your-storage-account-key"
 - name: containerName
 value: "your-container-name"
 ```

</TabItem>
</Tabs>

### Secret storage

Self-Deployed Runtime fetches secrets from a secret store to connect to the source systems. The secret store references are used to configure the workflow. Configure the secret store that aligns with your security infrastructure:

:::info Did you know?
Dapr supports additional secret stores which aren't mentioned here. For more information, see [Dapr secret store documentation](https://docs.dapr.io/reference/components-reference/supported-secret-stores/) for other configurations.
:::

:::warning Secret content format and naming
When storing credentials, follow the [secret naming and format requirements](https://docs.atlan.com/product/connections/self-deployed-runtime/how-tos/configure-workflow-execution#secret-content-format).
:::

<Tabs>
<TabItem value="aws-secret-manager" label="AWS Secret Manager" default>
 
 1. Locate the `secretstore` attribute in `values.yaml`.
 2. Add AWS Secret Manager configuration. For more information, see [AWS Secrets Manager](https://docs.dapr.io/reference/components-reference/supported-secret-stores/aws-secret-manager/)

 ```yaml
 secretstore:
 enabled: true
 spec:
 type: secretstores.aws.secretmanager
 version: v1
 metadata:
 - name: region # required, region in which secret is hosted
 value: <secret-region>
 # Needed if IAM authentication is not used
 - name: accessKey
 value: ""
 - name: secretKey
 value: ""
 ```

If you are using IAM role / IRSA authentication, leave `accessKey` and `secretKey` empty.

If you are using an IAM user instead, set:
- `accessKey` to the IAM user's access key ID
- `secretKey` to the IAM user's secret access key

That IAM user must have permission to read the target secret from AWS Secrets Manager:

```json
{
 "Version": "2012-10-17",
 "Statement": [
 {
 "Effect": "Allow",
 "Action": [
 "secretsmanager:GetSecretValue",
 "secretsmanager:DescribeSecret"
 ],
 "Resource": "arn:aws:secretsmanager:<region>:<account-id>:secret:<secret-name>*"
 }
 ]
}
```

:::note
Include the trailing `*` in the secret ARN. AWS appends a random suffix to secret names in the ARN, so omitting it can cause access failures.
:::

</TabItem>
<TabItem value="azure-key-vault" label="Azure Key Vault">

 1. Locate the `secretstore` attribute in `values.yaml`.
 2. Add Azure Key Vault configuration. For more information, see [Azure Key Vault secret store](https://docs.dapr.io/reference/components-reference/supported-secret-stores/azure-keyvault/)

 ```yaml
 secretstore:
 enabled: true
 spec:
 type: secretstores.azure.keyvault
 version: v1
 metadata:
 - name: vaultName
 value: "<your-keyvault-name>"
 - name: azureTenantId
 value: "<your-tenant-id>"
 - name: azureClientId
 value: "<your-client-id>"
 - name: azureClientSecret
 value: "<your-client-secret>"
 - name: azureEnvironment
 value: "AZUREPUBLICCLOUD" # Optional: AZUREPUBLICCLOUD, AZURECHINACLOUD, AZUREUSGOVERNMENTCLOUD, AZUREGERMANCLOUD
 ```
 Azure Key Vault supports multiple authentication methods:
 - **Client Secret**: Use `azureClientSecret` with tenant ID and client ID
 - **Certificate**: Use `azureCertificateFile` instead of client secret
 - **Managed Identity**: Omit authentication fields and use Azure managed identity

 For detailed authentication setup, see the [Authenticating to Azure](https://docs.dapr.io/developing-applications/integrations/azure/azure-authentication/authenticating-azure/) documentation.

</TabItem>
<TabItem value="gcp-secret-manager" label="GCP Secret Manager">

1. Locate the `secretstore` attribute in `values.yaml`.
2. Add Google Cloud Secret Manager configuration. For more information, see [GCP Secret Manager](https://docs.dapr.io/reference/components-reference/supported-secret-stores/gcp-secret-manager/)

 The GCP service account used in this configuration must have the `Secret Manager Secret Accessor` role (`roles/secretmanager.secretAccessor`) on the project where your secrets are stored. The metadata values below come from the service account's JSON key file.

 ```yaml
 secretstore:
 enabled: true
 spec:
 type: secretstores.gcp.secretmanager
 version: v1
 metadata:
 - name: type
 value: "service_account"
 - name: project_id
 value: "<project-id>"
 - name: private_key_id
 value: "<private-key-id>"
 - name: private_key
 value: "<private-key>"
 - name: client_email
 value: "<client-email>"
 - name: client_id
 value: "<client-id>"
 - name: auth_uri
 value: "https://accounts.google.com/o/oauth2/auth"
 - name: token_uri
 value: "https://oauth2.googleapis.com/token"
 - name: auth_provider_x509_cert_url
 value: "https://www.googleapis.com/oauth2/v1/certs"
 - name: client_x509_cert_url
 value: "https://www.googleapis.com/robot/v1/metadata/x509/<client-email>"
 ```

</TabItem>
<TabItem value="hashicorp-vault" label="HashiCorp Vault">

1. Locate the `secretstore` attribute in `values.yaml`.
2. Add HashiCorp Vault configuration. For more information, see [HashiCorp Vault](https://docs.dapr.io/reference/components-reference/supported-secret-stores/hashicorp-vault/)

 ```yaml
 secretstore:
 enabled: true
 spec:
 type: secretstores.hashicorp.vault
 version: v1
 metadata:
 - name: vaultAddr
 value: "[vault_address]" # Optional. Default: "https://127.0.0.1:8200"
 - name: caCert # Optional. This or caPath or caPem
 value: "[ca_cert]"
 - name: caPath # Optional. This or CaCert or caPem
 value: "[path_to_ca_cert_file]"
 - name: caPem # Optional. This or CaCert or CaPath
 value: "[encoded_ca_cert_pem]"
 - name: skipVerify # Optional. Default: false
 value: "[skip_tls_verification]"
 - name: tlsServerName # Optional.
 value: "[tls_config_server_name]"
 - name: vaultTokenMountPath # Required if vaultToken not provided. Path to token file.
 value: "[path_to_file_containing_token]"
 - name: vaultToken # Required if vaultTokenMountPath not provided. Token value.
 value: "[vault_token]"
 - name: vaultKVPrefix # Optional. Default: "dapr"
 value: "[vault_prefix]"
 - name: vaultKVUsePrefix # Optional. default: "true"
 value: "[true/false]"
 - name: enginePath # Optional. default: "secret"
 value: "secret"
 - name: vaultValueType # Optional. default: "map"
 value: "map"
 ```

</TabItem>
<TabItem value="kubernetes-secrets" label="Kubernetes Secrets">

1. Locate the `secretstore` attribute in `values.yaml`.
2. Add Kubernetes native secret storage. For more information, see [Kubernetes secrets](https://docs.dapr.io/reference/components-reference/supported-secret-stores/kubernetes-secret-store/)

 ```yaml
 secretstore:
 enabled: true
 spec:
 type: secretstores.kubernetes
 version: v1
 metadata:
 - name: defaultNamespace
 value: "default" # Optional: Default namespace to retrieve secrets from
 - name: kubeconfigPath
 value: "/path/to/kubeconfig" # Optional: Path to kubeconfig file
 ```
 When Dapr is deployed to a Kubernetes cluster, a secret store with the name `kubernetes` is automatically provisioned. You can use this native Kubernetes secret store with no need to create, deploy or maintain a component configuration file.

</TabItem>
<TabItem value="environment-variable-based" label="Environment Variables">

1. Locate the `secretstore` attribute in `values.yaml`.
2. Add Local environment variables as the spec. For more information, see [Local Environment Variables](https://docs.dapr.io/reference/components-reference/supported-secret-stores/envvar-secret-store/)

 ```yaml
 secretstore:
 enabled: true
 spec:
 type: secretstores.local.env
 version: v1
 ```

</TabItem>
</Tabs>

### Image source

Choose how the cluster pulls the app image. Most installs use Atlan's Docker Hub directly; mirror to a private registry if your organization requires it.

<Tabs>
<TabItem value="docker-hub" label="Public Docker Hub" default>

The chart pulls the app image from Atlan's Docker Hub at runtime. The pod needs a Kubernetes secret containing your Docker Hub PAT to authenticate:

```bash
kubectl create secret docker-registry atlan-docker-secret \
 --docker-server=docker.io \
 --docker-username=YOUR_USERNAME \
 --docker-password=YOUR_PAT_TOKEN \
 -n <namespace>
```

- Replace `YOUR_USERNAME` with the Docker Hub username provided by Atlan.
- Replace `YOUR_PAT_TOKEN` with the Personal Access Token (PAT) provided by Atlan.
- Replace `<namespace>` with the namespace you need to install the chart into. The secret and the release must live in the same namespace, or the pod fails with `ImagePullBackOff`.

The downloaded `values.yaml` already references this secret under `imagePullSecrets`. If you use a different secret name, update that field in the file.

</TabItem>
<TabItem value="private-registry" label="Private image repo">

Mirror the Atlan image to your enterprise registry and update `values.yaml` to point at it.

1. Authenticate with Docker Hub using the PAT from Atlan, then pull the source image. The image and tag come from `image.repository` and `image.tag` in the downloaded `values.yaml`:

 ```bash
 docker login -u atlanhq
 # When prompted for password, enter the PAT provided by Atlan
 docker pull <image.repository>:<image.tag>
 ```

2. Push the image to your enterprise's registry. Note down the new repository name and image tag.

3. Update `image.repository` and `image.tag` in `values.yaml` with the new values.

4. If your private registry requires authentication, create an image-pull secret in the target namespace and set `imagePullSecrets` in `values.yaml` to its name.

</TabItem>
</Tabs>

<h2 id="deploy-app">Deploy app</h2>

Follow these steps to deploy the secure app:

* Install the helm chart. The chart directory now carries your edited `values.yaml`, so no `-f` flag is needed:

 ```bash
 helm install {{deploymentValues.helmChartName}}-release ./{{deploymentValues.helmChartName}} -n <namespace>
 ```

 - Replace `<namespace>` with your target Kubernetes namespace.
 - The helm chart name `{{deploymentValues.helmChartName}}` is automatically used from your selected app.

The deployment process typically takes a few minutes to complete depending on factors like Kubernetes cluster resource availability, private image repository download time etc.

<h2 id="verify-app">Verify app</h2>

Follow these steps to verify deployment:

### Verify deployment status on cluster

1. Check pod status:

 ```bash
 kubectl get pods -n <namespace>
 ```

 The output appears similar to:

 ```
 NAME READY STATUS RESTARTS AGE
 <helm-chart-name>-release-<helm-chart-name>-5dff95cd85-cvk5z 1/1 Running 0 2m
 ```
 
 Replace `<helm-chart-name>` with your app's helm chart name (shown in the prerequisites section earlier in this guide).

 The pod status shows `Running` with `1/1` ready containers.

2. Verify logs for the running pod
 
 ```bash
 kubectl logs -n <namespace> -l app.kubernetes.io/name={{deploymentValues.helmChartName}} --tail=50 -f
 ```
 **Example application logs**: Look for these key log messages that confirm successful deployment:

 * `Uvicorn running on http://0.0.0.0:8000` - Web server started
 * `Workflow engine initialized` - Workflow processing ready
 * `dapr initialized. Status: Running` - Dapr runtime active
 * `Starting worker with task queue: atlan-<package-name>-DEPLOYMENT_NAME` - Worker process started (replace `<package-name>` with your app's package name)
 * `GET /server/ready 200` - Health check endpoint responding

### Verify registration via Atlan UI

Once the App is successfully deployed, it communicates to the Atlan tenant and registers itself. Verify App registration is successful in Atlan:

1. In the same Atlan tenant, navigate to **Workflows** > **Agent**.
2. Look for an entry named `<app_name>-<deployment_name>`, where `<app_name>` matches your selected app (for example, "Oracle" or "Microsoft SQL Server") and `<deployment_name>` is the deployment name you entered when generating the config.
3. Confirm the agent status displays as **Active**.

Agent registration and status takes a couple of minutes to reflect in the Atlan UI.

<h2 id="next-steps">Next steps</h2>

* [Configure workflow execution](https://docs.atlan.com/product/connections/self-deployed-runtime/how-tos/configure-workflow-execution): Set up workflow execution with secret retrieval for your Self-deployed Runtime

---

## Install on Kubernetes - SAP ECC

URL: https://docs.atlan.com/product/connections/self-deployed-runtime/how-tos/install-on-kubernetes
**Connector:** SAP ECC (erp)

> Install an App on Kubernetes using Helm charts, Docker images, and specific configuration

:::info **Did you know?** 
SDR requires additional enablement and licensing. Contact your Atlan representative for details.
:::

:::warning Use the guided install wizard instead
**New Self-Deployed Runtime setups are encouraged to use the [guided install wizard](https://docs.atlan.com/product/connections/self-deployed-runtime/how-tos/install-guided).** It assembles a complete guide tailored to your lifecycle mode, platform, and image procurement on a single page—and it's where new setup options (for example, HTTP proxy and custom CA trust) are documented going forward.

This page is kept for existing users who already reference it and may not include the latest steps.
:::

<h2 id="prerequisites">Prerequisites</h2>

Before you begin, make sure you have:

* `kubectl` installed and configured with administrative access to your target Kubernetes cluster
* Helm version 3.0 or later installed on your deployment machine
* A [Docker Hub Personal Access Token (PAT)](https://start.1password.com/open/i?a=WAVUZSKJO5GMNMVBYWAWECXIUE&v=ouvp3xf5334cxoamyiipzjlewy&i=p76avgzmkkcbftldcuvr5jcof4&h=atlanhq.1password.com) from Atlan
* App-specific helm chart name: `{{deploymentValues.helmChartName}}` 
* Object storage: AWS S3, Google Cloud Storage, or Azure Blob Storage with read/write permissions
* Secret store access: AWS Secret Manager, Azure Key Vault, GCP Secret Manager, HashiCorp Vault, or Kubernetes Secrets with read permissions

:::warning For security reasons, the Docker Hub PAT Token is regenerated on a periodic basis. 
In case the token is embedded in automation scripts or CI/CD pipelines, those jobs may fail. 
Contact your Atlan representative for the latest token.
:::

<h2 id="download-required-files">Download required files</h2>

<h3 id="download-helm-chart">Download Helm chart</h3>

Download the Helm chart for the app:

```bash
helm pull oci://registry-1.docker.io/atlanhq/{{deploymentValues.helmChartName}} --untar
```

This unpacks the chart's `Chart.yaml`, `templates/`, and a default `values.yaml` into `./{{deploymentValues.helmChartName}}/`. You'll replace this default `values.yaml` with your Marketplace copy in the next step.

<h3 id="download-values-yaml">Download values.yaml</h3>

Atlan generates the helm `values.yaml` for your runtime directly from the Marketplace UI, including the OAuth client credentials your runtime uses to authenticate to your tenant.

1. Sign in to your Atlan tenant as an administrator, open **Connector** > **Marketplace**, select the app you want to deploy, and click **Download config for Self-Deployed Runtime** in the right-hand sidebar.

2. In the dialog, keep **New deployment** selected (this mints the OAuth client and full config for a fresh runtime), choose **Kubernetes (Helm)** as the deployment target, and enter a **Deployment name**: a short identifier (lowercase letters, digits, and dashes) that identifies this runtime; the agent in **Workflows > Agent** is named `<app_name>-<deployment_name>`.

3. Click **Generate**. Atlan mints a dedicated OAuth client and produces a `values.yaml` file with:
 - `global.atlanBaseUrl`, `global.clientId`, and `global.clientSecret` already filled in.
 - `image.repository`, `image.tag`, and `name` pinned to the active version for your tenant.
 - `objectstore` and `secretstore` placeholders for you to configure below.

<h3 id="replace-chart-values">Replace chart values.yaml</h3>

Replace the default `values.yaml` inside the unpacked chart with the `values.yaml` you downloaded from the Marketplace.

From this point on, all edits to `values.yaml` must be made inside `./{{deploymentValues.helmChartName}}/`.

<h2 id="modify-values-yaml">Modify values.yaml</h2>

### Object storage

Self-Deployed Runtime needs a store for reading or writing files. Configure the object storage that matches your environment:

:::tip Don't see your preferred object store?
If your preferred object store isn't listed here, [reach out to Atlan support](https://docs.atlan.com/support/submit-request). Support for additional object stores may be available.
:::

<Tabs>
<TabItem value="aws-s3" label="AWS S3" default>

**Required permissions:**

Apply object-level actions to `arn:aws:s3:::BUCKET/*` and the list action to `arn:aws:s3:::BUCKET` in separate IAM statement entries.

| IAM action | Operations covered |
|---|---|
| `s3:GetObject` | GetObject (full and byte-range), HeadObject |
| `s3:PutObject` | PutObject, CreateMultipartUpload, UploadPart, CompleteMultipartUpload |
| `s3:AbortMultipartUpload` | Abort in-flight multipart upload on error (required for streaming write error paths) |
| `s3:DeleteObject` | DeleteObject and DeleteObjects (bulk batch—same IAM action) |
| `s3:ListBucket` | ListObjectsV2—bucket-level permission, not object-level |

```json
{
 "Version": "2012-10-17",
 "Statement": [
 {
 "Effect": "Allow",
 "Action": [
 "s3:GetObject",
 "s3:PutObject",
 "s3:AbortMultipartUpload",
 "s3:DeleteObject"
 ],
 "Resource": "arn:aws:s3:::YOUR-BUCKET/*"
 },
 {
 "Effect": "Allow",
 "Action": "s3:ListBucket",
 "Resource": "arn:aws:s3:::YOUR-BUCKET"
 }
 ]
}
```

**AssumeRole**: when using `assumeRoleArn`, the caller identity additionally needs `sts:AssumeRole` on the target role ARN. The role itself holds the bucket policy described earlier.

**Configure:**

 1. Locate the `objectstore` attribute in `values.yaml`.
 2. Add AWS S3 configuration. For more information, see [AWS S3 Binding Spec](https://docs.dapr.io/reference/components-reference/supported-bindings/s3/).

 ```yaml
 objectstore:
 enabled: true
 spec:
 type: bindings.aws.s3
 version: v1
 metadata:
 - name: accessKey #optional, leave this empty for iam authentication
 value: ""
 - name: secretKey #optional, leave this empty for iam authentication
 value: ""
 - name: bucket #required, name of the bucket where application can write
 value: "<bucket-name>"
 - name: region #required, region of the bucket where application can write
 value: "<bucket-region>"
 - name: forcePathStyle
 value: "true"
 ```

</TabItem>
<TabItem value="gcp-storage" label="Google Cloud Storage">

**Required permissions:**

| IAM permission | Operations covered |
|---|---|
| `storage.objects.get` | GetObject (full and byte-range), object metadata / HeadObject equivalent |
| `storage.objects.create` | PutObject, resumable / streaming write |
| `storage.objects.delete` | DeleteObject (GCS has no native bulk-delete API—`delete_prefix` issues parallel single-object deletes) |
| `storage.objects.list` | ListObjects |

No `storage.buckets.*` permissions are needed. The smallest predefined role that covers all four is **`roles/storage.objectAdmin`** scoped to the bucket. Alternatively, create a custom role with exactly these four permissions.

**Configure:**

 1. Locate the `objectstore` attribute in `values.yaml`.
 2. Add Google Cloud Storage configuration. For more information, see [GCP Storage Bucket binding spec](https://docs.dapr.io/reference/components-reference/supported-bindings/gcpbucket/)

 ```yaml
 objectstore:
 enabled: true
 spec:
 type: bindings.gcp.bucket
 version: v1
 metadata:
 - name: bucket
 value: "your-gcs-bucket-name"
 - name: type
 value: "service_account"
 - name: project_id
 value: "your-gcp-project-id"
 ```

</TabItem>
<TabItem value="azure-blob" label="Azure Blob Storage">

**Required permissions:**

**RBAC**—assign at container or storage-account scope:

| RBAC action | Operations covered |
|---|---|
| `Microsoft.Storage/storageAccounts/blobServices/containers/blobs/read` | GetBlob, GetBlobProperties (HEAD), ListBlobs, byte-range GET |
| `Microsoft.Storage/storageAccounts/blobServices/containers/blobs/write` | PutBlob, PutBlock + PutBlockList (streaming / block write) |
| `Microsoft.Storage/storageAccounts/blobServices/containers/blobs/delete` | DeleteBlob, BlobBatch delete (bulk—up to 256 keys per request) |

The smallest predefined role covering all three is **`Storage Blob Data Contributor`**. `Storage Blob Data Owner` is a superset and is only needed if you additionally require POSIX ACL management on ADLS Gen2.

**SAS token**—minimum permissions at container scope: `r` (read) + `w` (write) + `d` (delete) + `l` (list), that is a container-scoped SAS with **`rwdl`**.

**ADLS Gen2 with POSIX ACLs**: if the storage account has hierarchical namespace enabled and you use ACL-based access control instead of RBAC, the principal needs Execute (`X`) on every parent directory and Read / Write / Delete on the objects in scope. RBAC (`Storage Blob Data Contributor`) is simpler and is recommended unless you have a specific ACL requirement.

**Configure:**

 1. Locate the `objectstore` attribute in `values.yaml`.
 2. Add Azure Blob Storage configuration. For more information, see [Azure Blob Storage binding spec](https://docs.dapr.io/reference/components-reference/supported-bindings/blobstorage/)

 ```yaml
 objectstore:
 enabled: true
 spec:
 type: bindings.azure.blobstorage
 version: v1
 metadata:
 - name: accountName
 value: "your-storage-account-name"
 - name: accountKey
 value: "your-storage-account-key"
 - name: containerName
 value: "your-container-name"
 ```

</TabItem>
</Tabs>

### Secret storage

Self-Deployed Runtime fetches secrets from a secret store to connect to the source systems. The secret store references are used to configure the workflow. Configure the secret store that aligns with your security infrastructure:

:::info Did you know?
Dapr supports additional secret stores which aren't mentioned here. For more information, see [Dapr secret store documentation](https://docs.dapr.io/reference/components-reference/supported-secret-stores/) for other configurations.
:::

:::warning Secret content format and naming
When storing credentials, follow the [secret naming and format requirements](https://docs.atlan.com/product/connections/self-deployed-runtime/how-tos/configure-workflow-execution#secret-content-format).
:::

<Tabs>
<TabItem value="aws-secret-manager" label="AWS Secret Manager" default>
 
 1. Locate the `secretstore` attribute in `values.yaml`.
 2. Add AWS Secret Manager configuration. For more information, see [AWS Secrets Manager](https://docs.dapr.io/reference/components-reference/supported-secret-stores/aws-secret-manager/)

 ```yaml
 secretstore:
 enabled: true
 spec:
 type: secretstores.aws.secretmanager
 version: v1
 metadata:
 - name: region # required, region in which secret is hosted
 value: <secret-region>
 # Needed if IAM authentication is not used
 - name: accessKey
 value: ""
 - name: secretKey
 value: ""
 ```

If you are using IAM role / IRSA authentication, leave `accessKey` and `secretKey` empty.

If you are using an IAM user instead, set:
- `accessKey` to the IAM user's access key ID
- `secretKey` to the IAM user's secret access key

That IAM user must have permission to read the target secret from AWS Secrets Manager:

```json
{
 "Version": "2012-10-17",
 "Statement": [
 {
 "Effect": "Allow",
 "Action": [
 "secretsmanager:GetSecretValue",
 "secretsmanager:DescribeSecret"
 ],
 "Resource": "arn:aws:secretsmanager:<region>:<account-id>:secret:<secret-name>*"
 }
 ]
}
```

:::note
Include the trailing `*` in the secret ARN. AWS appends a random suffix to secret names in the ARN, so omitting it can cause access failures.
:::

</TabItem>
<TabItem value="azure-key-vault" label="Azure Key Vault">

 1. Locate the `secretstore` attribute in `values.yaml`.
 2. Add Azure Key Vault configuration. For more information, see [Azure Key Vault secret store](https://docs.dapr.io/reference/components-reference/supported-secret-stores/azure-keyvault/)

 ```yaml
 secretstore:
 enabled: true
 spec:
 type: secretstores.azure.keyvault
 version: v1
 metadata:
 - name: vaultName
 value: "<your-keyvault-name>"
 - name: azureTenantId
 value: "<your-tenant-id>"
 - name: azureClientId
 value: "<your-client-id>"
 - name: azureClientSecret
 value: "<your-client-secret>"
 - name: azureEnvironment
 value: "AZUREPUBLICCLOUD" # Optional: AZUREPUBLICCLOUD, AZURECHINACLOUD, AZUREUSGOVERNMENTCLOUD, AZUREGERMANCLOUD
 ```
 Azure Key Vault supports multiple authentication methods:
 - **Client Secret**: Use `azureClientSecret` with tenant ID and client ID
 - **Certificate**: Use `azureCertificateFile` instead of client secret
 - **Managed Identity**: Omit authentication fields and use Azure managed identity

 For detailed authentication setup, see the [Authenticating to Azure](https://docs.dapr.io/developing-applications/integrations/azure/azure-authentication/authenticating-azure/) documentation.

</TabItem>
<TabItem value="gcp-secret-manager" label="GCP Secret Manager">

1. Locate the `secretstore` attribute in `values.yaml`.
2. Add Google Cloud Secret Manager configuration. For more information, see [GCP Secret Manager](https://docs.dapr.io/reference/components-reference/supported-secret-stores/gcp-secret-manager/)

 The GCP service account used in this configuration must have the `Secret Manager Secret Accessor` role (`roles/secretmanager.secretAccessor`) on the project where your secrets are stored. The metadata values below come from the service account's JSON key file.

 ```yaml
 secretstore:
 enabled: true
 spec:
 type: secretstores.gcp.secretmanager
 version: v1
 metadata:
 - name: type
 value: "service_account"
 - name: project_id
 value: "<project-id>"
 - name: private_key_id
 value: "<private-key-id>"
 - name: private_key
 value: "<private-key>"
 - name: client_email
 value: "<client-email>"
 - name: client_id
 value: "<client-id>"
 - name: auth_uri
 value: "https://accounts.google.com/o/oauth2/auth"
 - name: token_uri
 value: "https://oauth2.googleapis.com/token"
 - name: auth_provider_x509_cert_url
 value: "https://www.googleapis.com/oauth2/v1/certs"
 - name: client_x509_cert_url
 value: "https://www.googleapis.com/robot/v1/metadata/x509/<client-email>"
 ```

</TabItem>
<TabItem value="hashicorp-vault" label="HashiCorp Vault">

1. Locate the `secretstore` attribute in `values.yaml`.
2. Add HashiCorp Vault configuration. For more information, see [HashiCorp Vault](https://docs.dapr.io/reference/components-reference/supported-secret-stores/hashicorp-vault/)

 ```yaml
 secretstore:
 enabled: true
 spec:
 type: secretstores.hashicorp.vault
 version: v1
 metadata:
 - name: vaultAddr
 value: "[vault_address]" # Optional. Default: "https://127.0.0.1:8200"
 - name: caCert # Optional. This or caPath or caPem
 value: "[ca_cert]"
 - name: caPath # Optional. This or CaCert or caPem
 value: "[path_to_ca_cert_file]"
 - name: caPem # Optional. This or CaCert or CaPath
 value: "[encoded_ca_cert_pem]"
 - name: skipVerify # Optional. Default: false
 value: "[skip_tls_verification]"
 - name: tlsServerName # Optional.
 value: "[tls_config_server_name]"
 - name: vaultTokenMountPath # Required if vaultToken not provided. Path to token file.
 value: "[path_to_file_containing_token]"
 - name: vaultToken # Required if vaultTokenMountPath not provided. Token value.
 value: "[vault_token]"
 - name: vaultKVPrefix # Optional. Default: "dapr"
 value: "[vault_prefix]"
 - name: vaultKVUsePrefix # Optional. default: "true"
 value: "[true/false]"
 - name: enginePath # Optional. default: "secret"
 value: "secret"
 - name: vaultValueType # Optional. default: "map"
 value: "map"
 ```

</TabItem>
<TabItem value="kubernetes-secrets" label="Kubernetes Secrets">

1. Locate the `secretstore` attribute in `values.yaml`.
2. Add Kubernetes native secret storage. For more information, see [Kubernetes secrets](https://docs.dapr.io/reference/components-reference/supported-secret-stores/kubernetes-secret-store/)

 ```yaml
 secretstore:
 enabled: true
 spec:
 type: secretstores.kubernetes
 version: v1
 metadata:
 - name: defaultNamespace
 value: "default" # Optional: Default namespace to retrieve secrets from
 - name: kubeconfigPath
 value: "/path/to/kubeconfig" # Optional: Path to kubeconfig file
 ```
 When Dapr is deployed to a Kubernetes cluster, a secret store with the name `kubernetes` is automatically provisioned. You can use this native Kubernetes secret store with no need to create, deploy or maintain a component configuration file.

</TabItem>
<TabItem value="environment-variable-based" label="Environment Variables">

1. Locate the `secretstore` attribute in `values.yaml`.
2. Add Local environment variables as the spec. For more information, see [Local Environment Variables](https://docs.dapr.io/reference/components-reference/supported-secret-stores/envvar-secret-store/)

 ```yaml
 secretstore:
 enabled: true
 spec:
 type: secretstores.local.env
 version: v1
 ```

</TabItem>
</Tabs>

### Image source

Choose how the cluster pulls the app image. Most installs use Atlan's Docker Hub directly; mirror to a private registry if your organization requires it.

<Tabs>
<TabItem value="docker-hub" label="Public Docker Hub" default>

The chart pulls the app image from Atlan's Docker Hub at runtime. The pod needs a Kubernetes secret containing your Docker Hub PAT to authenticate:

```bash
kubectl create secret docker-registry atlan-docker-secret \
 --docker-server=docker.io \
 --docker-username=YOUR_USERNAME \
 --docker-password=YOUR_PAT_TOKEN \
 -n <namespace>
```

- Replace `YOUR_USERNAME` with the Docker Hub username provided by Atlan.
- Replace `YOUR_PAT_TOKEN` with the Personal Access Token (PAT) provided by Atlan.
- Replace `<namespace>` with the namespace you need to install the chart into. The secret and the release must live in the same namespace, or the pod fails with `ImagePullBackOff`.

The downloaded `values.yaml` already references this secret under `imagePullSecrets`. If you use a different secret name, update that field in the file.

</TabItem>
<TabItem value="private-registry" label="Private image repo">

Mirror the Atlan image to your enterprise registry and update `values.yaml` to point at it.

1. Authenticate with Docker Hub using the PAT from Atlan, then pull the source image. The image and tag come from `image.repository` and `image.tag` in the downloaded `values.yaml`:

 ```bash
 docker login -u atlanhq
 # When prompted for password, enter the PAT provided by Atlan
 docker pull <image.repository>:<image.tag>
 ```

2. Push the image to your enterprise's registry. Note down the new repository name and image tag.

3. Update `image.repository` and `image.tag` in `values.yaml` with the new values.

4. If your private registry requires authentication, create an image-pull secret in the target namespace and set `imagePullSecrets` in `values.yaml` to its name.

</TabItem>
</Tabs>

<h2 id="deploy-app">Deploy app</h2>

Follow these steps to deploy the secure app:

* Install the helm chart. The chart directory now carries your edited `values.yaml`, so no `-f` flag is needed:

 ```bash
 helm install {{deploymentValues.helmChartName}}-release ./{{deploymentValues.helmChartName}} -n <namespace>
 ```

 - Replace `<namespace>` with your target Kubernetes namespace.
 - The helm chart name `{{deploymentValues.helmChartName}}` is automatically used from your selected app.

The deployment process typically takes a few minutes to complete depending on factors like Kubernetes cluster resource availability, private image repository download time etc.

<h2 id="verify-app">Verify app</h2>

Follow these steps to verify deployment:

### Verify deployment status on cluster

1. Check pod status:

 ```bash
 kubectl get pods -n <namespace>
 ```

 The output appears similar to:

 ```
 NAME READY STATUS RESTARTS AGE
 <helm-chart-name>-release-<helm-chart-name>-5dff95cd85-cvk5z 1/1 Running 0 2m
 ```
 
 Replace `<helm-chart-name>` with your app's helm chart name (shown in the prerequisites section earlier in this guide).

 The pod status shows `Running` with `1/1` ready containers.

2. Verify logs for the running pod
 
 ```bash
 kubectl logs -n <namespace> -l app.kubernetes.io/name={{deploymentValues.helmChartName}} --tail=50 -f
 ```
 **Example application logs**: Look for these key log messages that confirm successful deployment:

 * `Uvicorn running on http://0.0.0.0:8000` - Web server started
 * `Workflow engine initialized` - Workflow processing ready
 * `dapr initialized. Status: Running` - Dapr runtime active
 * `Starting worker with task queue: atlan-<package-name>-DEPLOYMENT_NAME` - Worker process started (replace `<package-name>` with your app's package name)
 * `GET /server/ready 200` - Health check endpoint responding

### Verify registration via Atlan UI

Once the App is successfully deployed, it communicates to the Atlan tenant and registers itself. Verify App registration is successful in Atlan:

1. In the same Atlan tenant, navigate to **Workflows** > **Agent**.
2. Look for an entry named `<app_name>-<deployment_name>`, where `<app_name>` matches your selected app (for example, "Oracle" or "Microsoft SQL Server") and `<deployment_name>` is the deployment name you entered when generating the config.
3. Confirm the agent status displays as **Active**.

Agent registration and status takes a couple of minutes to reflect in the Atlan UI.

<h2 id="next-steps">Next steps</h2>

* [Configure workflow execution](https://docs.atlan.com/product/connections/self-deployed-runtime/how-tos/configure-workflow-execution): Set up workflow execution with secret retrieval for your Self-deployed Runtime

---

## Install on Kubernetes - SAP S/4HANA

URL: https://docs.atlan.com/product/connections/self-deployed-runtime/how-tos/install-on-kubernetes
**Connector:** SAP S/4HANA (erp)

> Install an App on Kubernetes using Helm charts, Docker images, and specific configuration

:::info **Did you know?** 
SDR requires additional enablement and licensing. Contact your Atlan representative for details.
:::

:::warning Use the guided install wizard instead
**New Self-Deployed Runtime setups are encouraged to use the [guided install wizard](https://docs.atlan.com/product/connections/self-deployed-runtime/how-tos/install-guided).** It assembles a complete guide tailored to your lifecycle mode, platform, and image procurement on a single page—and it's where new setup options (for example, HTTP proxy and custom CA trust) are documented going forward.

This page is kept for existing users who already reference it and may not include the latest steps.
:::

<h2 id="prerequisites">Prerequisites</h2>

Before you begin, make sure you have:

* `kubectl` installed and configured with administrative access to your target Kubernetes cluster
* Helm version 3.0 or later installed on your deployment machine
* A [Docker Hub Personal Access Token (PAT)](https://start.1password.com/open/i?a=WAVUZSKJO5GMNMVBYWAWECXIUE&v=ouvp3xf5334cxoamyiipzjlewy&i=p76avgzmkkcbftldcuvr5jcof4&h=atlanhq.1password.com) from Atlan
* App-specific helm chart name: `{{deploymentValues.helmChartName}}` 
* Object storage: AWS S3, Google Cloud Storage, or Azure Blob Storage with read/write permissions
* Secret store access: AWS Secret Manager, Azure Key Vault, GCP Secret Manager, HashiCorp Vault, or Kubernetes Secrets with read permissions

:::warning For security reasons, the Docker Hub PAT Token is regenerated on a periodic basis. 
In case the token is embedded in automation scripts or CI/CD pipelines, those jobs may fail. 
Contact your Atlan representative for the latest token.
:::

<h2 id="download-required-files">Download required files</h2>

<h3 id="download-helm-chart">Download Helm chart</h3>

Download the Helm chart for the app:

```bash
helm pull oci://registry-1.docker.io/atlanhq/{{deploymentValues.helmChartName}} --untar
```

This unpacks the chart's `Chart.yaml`, `templates/`, and a default `values.yaml` into `./{{deploymentValues.helmChartName}}/`. You'll replace this default `values.yaml` with your Marketplace copy in the next step.

<h3 id="download-values-yaml">Download values.yaml</h3>

Atlan generates the helm `values.yaml` for your runtime directly from the Marketplace UI, including the OAuth client credentials your runtime uses to authenticate to your tenant.

1. Sign in to your Atlan tenant as an administrator, open **Connector** > **Marketplace**, select the app you want to deploy, and click **Download config for Self-Deployed Runtime** in the right-hand sidebar.

2. In the dialog, keep **New deployment** selected (this mints the OAuth client and full config for a fresh runtime), choose **Kubernetes (Helm)** as the deployment target, and enter a **Deployment name**: a short identifier (lowercase letters, digits, and dashes) that identifies this runtime; the agent in **Workflows > Agent** is named `<app_name>-<deployment_name>`.

3. Click **Generate**. Atlan mints a dedicated OAuth client and produces a `values.yaml` file with:
 - `global.atlanBaseUrl`, `global.clientId`, and `global.clientSecret` already filled in.
 - `image.repository`, `image.tag`, and `name` pinned to the active version for your tenant.
 - `objectstore` and `secretstore` placeholders for you to configure below.

<h3 id="replace-chart-values">Replace chart values.yaml</h3>

Replace the default `values.yaml` inside the unpacked chart with the `values.yaml` you downloaded from the Marketplace.

From this point on, all edits to `values.yaml` must be made inside `./{{deploymentValues.helmChartName}}/`.

<h2 id="modify-values-yaml">Modify values.yaml</h2>

### Object storage

Self-Deployed Runtime needs a store for reading or writing files. Configure the object storage that matches your environment:

:::tip Don't see your preferred object store?
If your preferred object store isn't listed here, [reach out to Atlan support](https://docs.atlan.com/support/submit-request). Support for additional object stores may be available.
:::

<Tabs>
<TabItem value="aws-s3" label="AWS S3" default>

**Required permissions:**

Apply object-level actions to `arn:aws:s3:::BUCKET/*` and the list action to `arn:aws:s3:::BUCKET` in separate IAM statement entries.

| IAM action | Operations covered |
|---|---|
| `s3:GetObject` | GetObject (full and byte-range), HeadObject |
| `s3:PutObject` | PutObject, CreateMultipartUpload, UploadPart, CompleteMultipartUpload |
| `s3:AbortMultipartUpload` | Abort in-flight multipart upload on error (required for streaming write error paths) |
| `s3:DeleteObject` | DeleteObject and DeleteObjects (bulk batch—same IAM action) |
| `s3:ListBucket` | ListObjectsV2—bucket-level permission, not object-level |

```json
{
 "Version": "2012-10-17",
 "Statement": [
 {
 "Effect": "Allow",
 "Action": [
 "s3:GetObject",
 "s3:PutObject",
 "s3:AbortMultipartUpload",
 "s3:DeleteObject"
 ],
 "Resource": "arn:aws:s3:::YOUR-BUCKET/*"
 },
 {
 "Effect": "Allow",
 "Action": "s3:ListBucket",
 "Resource": "arn:aws:s3:::YOUR-BUCKET"
 }
 ]
}
```

**AssumeRole**: when using `assumeRoleArn`, the caller identity additionally needs `sts:AssumeRole` on the target role ARN. The role itself holds the bucket policy described earlier.

**Configure:**

 1. Locate the `objectstore` attribute in `values.yaml`.
 2. Add AWS S3 configuration. For more information, see [AWS S3 Binding Spec](https://docs.dapr.io/reference/components-reference/supported-bindings/s3/).

 ```yaml
 objectstore:
 enabled: true
 spec:
 type: bindings.aws.s3
 version: v1
 metadata:
 - name: accessKey #optional, leave this empty for iam authentication
 value: ""
 - name: secretKey #optional, leave this empty for iam authentication
 value: ""
 - name: bucket #required, name of the bucket where application can write
 value: "<bucket-name>"
 - name: region #required, region of the bucket where application can write
 value: "<bucket-region>"
 - name: forcePathStyle
 value: "true"
 ```

</TabItem>
<TabItem value="gcp-storage" label="Google Cloud Storage">

**Required permissions:**

| IAM permission | Operations covered |
|---|---|
| `storage.objects.get` | GetObject (full and byte-range), object metadata / HeadObject equivalent |
| `storage.objects.create` | PutObject, resumable / streaming write |
| `storage.objects.delete` | DeleteObject (GCS has no native bulk-delete API—`delete_prefix` issues parallel single-object deletes) |
| `storage.objects.list` | ListObjects |

No `storage.buckets.*` permissions are needed. The smallest predefined role that covers all four is **`roles/storage.objectAdmin`** scoped to the bucket. Alternatively, create a custom role with exactly these four permissions.

**Configure:**

 1. Locate the `objectstore` attribute in `values.yaml`.
 2. Add Google Cloud Storage configuration. For more information, see [GCP Storage Bucket binding spec](https://docs.dapr.io/reference/components-reference/supported-bindings/gcpbucket/)

 ```yaml
 objectstore:
 enabled: true
 spec:
 type: bindings.gcp.bucket
 version: v1
 metadata:
 - name: bucket
 value: "your-gcs-bucket-name"
 - name: type
 value: "service_account"
 - name: project_id
 value: "your-gcp-project-id"
 ```

</TabItem>
<TabItem value="azure-blob" label="Azure Blob Storage">

**Required permissions:**

**RBAC**—assign at container or storage-account scope:

| RBAC action | Operations covered |
|---|---|
| `Microsoft.Storage/storageAccounts/blobServices/containers/blobs/read` | GetBlob, GetBlobProperties (HEAD), ListBlobs, byte-range GET |
| `Microsoft.Storage/storageAccounts/blobServices/containers/blobs/write` | PutBlob, PutBlock + PutBlockList (streaming / block write) |
| `Microsoft.Storage/storageAccounts/blobServices/containers/blobs/delete` | DeleteBlob, BlobBatch delete (bulk—up to 256 keys per request) |

The smallest predefined role covering all three is **`Storage Blob Data Contributor`**. `Storage Blob Data Owner` is a superset and is only needed if you additionally require POSIX ACL management on ADLS Gen2.

**SAS token**—minimum permissions at container scope: `r` (read) + `w` (write) + `d` (delete) + `l` (list), that is a container-scoped SAS with **`rwdl`**.

**ADLS Gen2 with POSIX ACLs**: if the storage account has hierarchical namespace enabled and you use ACL-based access control instead of RBAC, the principal needs Execute (`X`) on every parent directory and Read / Write / Delete on the objects in scope. RBAC (`Storage Blob Data Contributor`) is simpler and is recommended unless you have a specific ACL requirement.

**Configure:**

 1. Locate the `objectstore` attribute in `values.yaml`.
 2. Add Azure Blob Storage configuration. For more information, see [Azure Blob Storage binding spec](https://docs.dapr.io/reference/components-reference/supported-bindings/blobstorage/)

 ```yaml
 objectstore:
 enabled: true
 spec:
 type: bindings.azure.blobstorage
 version: v1
 metadata:
 - name: accountName
 value: "your-storage-account-name"
 - name: accountKey
 value: "your-storage-account-key"
 - name: containerName
 value: "your-container-name"
 ```

</TabItem>
</Tabs>

### Secret storage

Self-Deployed Runtime fetches secrets from a secret store to connect to the source systems. The secret store references are used to configure the workflow. Configure the secret store that aligns with your security infrastructure:

:::info Did you know?
Dapr supports additional secret stores which aren't mentioned here. For more information, see [Dapr secret store documentation](https://docs.dapr.io/reference/components-reference/supported-secret-stores/) for other configurations.
:::

:::warning Secret content format and naming
When storing credentials, follow the [secret naming and format requirements](https://docs.atlan.com/product/connections/self-deployed-runtime/how-tos/configure-workflow-execution#secret-content-format).
:::

<Tabs>
<TabItem value="aws-secret-manager" label="AWS Secret Manager" default>
 
 1. Locate the `secretstore` attribute in `values.yaml`.
 2. Add AWS Secret Manager configuration. For more information, see [AWS Secrets Manager](https://docs.dapr.io/reference/components-reference/supported-secret-stores/aws-secret-manager/)

 ```yaml
 secretstore:
 enabled: true
 spec:
 type: secretstores.aws.secretmanager
 version: v1
 metadata:
 - name: region # required, region in which secret is hosted
 value: <secret-region>
 # Needed if IAM authentication is not used
 - name: accessKey
 value: ""
 - name: secretKey
 value: ""
 ```

If you are using IAM role / IRSA authentication, leave `accessKey` and `secretKey` empty.

If you are using an IAM user instead, set:
- `accessKey` to the IAM user's access key ID
- `secretKey` to the IAM user's secret access key

That IAM user must have permission to read the target secret from AWS Secrets Manager:

```json
{
 "Version": "2012-10-17",
 "Statement": [
 {
 "Effect": "Allow",
 "Action": [
 "secretsmanager:GetSecretValue",
 "secretsmanager:DescribeSecret"
 ],
 "Resource": "arn:aws:secretsmanager:<region>:<account-id>:secret:<secret-name>*"
 }
 ]
}
```

:::note
Include the trailing `*` in the secret ARN. AWS appends a random suffix to secret names in the ARN, so omitting it can cause access failures.
:::

</TabItem>
<TabItem value="azure-key-vault" label="Azure Key Vault">

 1. Locate the `secretstore` attribute in `values.yaml`.
 2. Add Azure Key Vault configuration. For more information, see [Azure Key Vault secret store](https://docs.dapr.io/reference/components-reference/supported-secret-stores/azure-keyvault/)

 ```yaml
 secretstore:
 enabled: true
 spec:
 type: secretstores.azure.keyvault
 version: v1
 metadata:
 - name: vaultName
 value: "<your-keyvault-name>"
 - name: azureTenantId
 value: "<your-tenant-id>"
 - name: azureClientId
 value: "<your-client-id>"
 - name: azureClientSecret
 value: "<your-client-secret>"
 - name: azureEnvironment
 value: "AZUREPUBLICCLOUD" # Optional: AZUREPUBLICCLOUD, AZURECHINACLOUD, AZUREUSGOVERNMENTCLOUD, AZUREGERMANCLOUD
 ```
 Azure Key Vault supports multiple authentication methods:
 - **Client Secret**: Use `azureClientSecret` with tenant ID and client ID
 - **Certificate**: Use `azureCertificateFile` instead of client secret
 - **Managed Identity**: Omit authentication fields and use Azure managed identity

 For detailed authentication setup, see the [Authenticating to Azure](https://docs.dapr.io/developing-applications/integrations/azure/azure-authentication/authenticating-azure/) documentation.

</TabItem>
<TabItem value="gcp-secret-manager" label="GCP Secret Manager">

1. Locate the `secretstore` attribute in `values.yaml`.
2. Add Google Cloud Secret Manager configuration. For more information, see [GCP Secret Manager](https://docs.dapr.io/reference/components-reference/supported-secret-stores/gcp-secret-manager/)

 The GCP service account used in this configuration must have the `Secret Manager Secret Accessor` role (`roles/secretmanager.secretAccessor`) on the project where your secrets are stored. The metadata values below come from the service account's JSON key file.

 ```yaml
 secretstore:
 enabled: true
 spec:
 type: secretstores.gcp.secretmanager
 version: v1
 metadata:
 - name: type
 value: "service_account"
 - name: project_id
 value: "<project-id>"
 - name: private_key_id
 value: "<private-key-id>"
 - name: private_key
 value: "<private-key>"
 - name: client_email
 value: "<client-email>"
 - name: client_id
 value: "<client-id>"
 - name: auth_uri
 value: "https://accounts.google.com/o/oauth2/auth"
 - name: token_uri
 value: "https://oauth2.googleapis.com/token"
 - name: auth_provider_x509_cert_url
 value: "https://www.googleapis.com/oauth2/v1/certs"
 - name: client_x509_cert_url
 value: "https://www.googleapis.com/robot/v1/metadata/x509/<client-email>"
 ```

</TabItem>
<TabItem value="hashicorp-vault" label="HashiCorp Vault">

1. Locate the `secretstore` attribute in `values.yaml`.
2. Add HashiCorp Vault configuration. For more information, see [HashiCorp Vault](https://docs.dapr.io/reference/components-reference/supported-secret-stores/hashicorp-vault/)

 ```yaml
 secretstore:
 enabled: true
 spec:
 type: secretstores.hashicorp.vault
 version: v1
 metadata:
 - name: vaultAddr
 value: "[vault_address]" # Optional. Default: "https://127.0.0.1:8200"
 - name: caCert # Optional. This or caPath or caPem
 value: "[ca_cert]"
 - name: caPath # Optional. This or CaCert or caPem
 value: "[path_to_ca_cert_file]"
 - name: caPem # Optional. This or CaCert or CaPath
 value: "[encoded_ca_cert_pem]"
 - name: skipVerify # Optional. Default: false
 value: "[skip_tls_verification]"
 - name: tlsServerName # Optional.
 value: "[tls_config_server_name]"
 - name: vaultTokenMountPath # Required if vaultToken not provided. Path to token file.
 value: "[path_to_file_containing_token]"
 - name: vaultToken # Required if vaultTokenMountPath not provided. Token value.
 value: "[vault_token]"
 - name: vaultKVPrefix # Optional. Default: "dapr"
 value: "[vault_prefix]"
 - name: vaultKVUsePrefix # Optional. default: "true"
 value: "[true/false]"
 - name: enginePath # Optional. default: "secret"
 value: "secret"
 - name: vaultValueType # Optional. default: "map"
 value: "map"
 ```

</TabItem>
<TabItem value="kubernetes-secrets" label="Kubernetes Secrets">

1. Locate the `secretstore` attribute in `values.yaml`.
2. Add Kubernetes native secret storage. For more information, see [Kubernetes secrets](https://docs.dapr.io/reference/components-reference/supported-secret-stores/kubernetes-secret-store/)

 ```yaml
 secretstore:
 enabled: true
 spec:
 type: secretstores.kubernetes
 version: v1
 metadata:
 - name: defaultNamespace
 value: "default" # Optional: Default namespace to retrieve secrets from
 - name: kubeconfigPath
 value: "/path/to/kubeconfig" # Optional: Path to kubeconfig file
 ```
 When Dapr is deployed to a Kubernetes cluster, a secret store with the name `kubernetes` is automatically provisioned. You can use this native Kubernetes secret store with no need to create, deploy or maintain a component configuration file.

</TabItem>
<TabItem value="environment-variable-based" label="Environment Variables">

1. Locate the `secretstore` attribute in `values.yaml`.
2. Add Local environment variables as the spec. For more information, see [Local Environment Variables](https://docs.dapr.io/reference/components-reference/supported-secret-stores/envvar-secret-store/)

 ```yaml
 secretstore:
 enabled: true
 spec:
 type: secretstores.local.env
 version: v1
 ```

</TabItem>
</Tabs>

### Image source

Choose how the cluster pulls the app image. Most installs use Atlan's Docker Hub directly; mirror to a private registry if your organization requires it.

<Tabs>
<TabItem value="docker-hub" label="Public Docker Hub" default>

The chart pulls the app image from Atlan's Docker Hub at runtime. The pod needs a Kubernetes secret containing your Docker Hub PAT to authenticate:

```bash
kubectl create secret docker-registry atlan-docker-secret \
 --docker-server=docker.io \
 --docker-username=YOUR_USERNAME \
 --docker-password=YOUR_PAT_TOKEN \
 -n <namespace>
```

- Replace `YOUR_USERNAME` with the Docker Hub username provided by Atlan.
- Replace `YOUR_PAT_TOKEN` with the Personal Access Token (PAT) provided by Atlan.
- Replace `<namespace>` with the namespace you need to install the chart into. The secret and the release must live in the same namespace, or the pod fails with `ImagePullBackOff`.

The downloaded `values.yaml` already references this secret under `imagePullSecrets`. If you use a different secret name, update that field in the file.

</TabItem>
<TabItem value="private-registry" label="Private image repo">

Mirror the Atlan image to your enterprise registry and update `values.yaml` to point at it.

1. Authenticate with Docker Hub using the PAT from Atlan, then pull the source image. The image and tag come from `image.repository` and `image.tag` in the downloaded `values.yaml`:

 ```bash
 docker login -u atlanhq
 # When prompted for password, enter the PAT provided by Atlan
 docker pull <image.repository>:<image.tag>
 ```

2. Push the image to your enterprise's registry. Note down the new repository name and image tag.

3. Update `image.repository` and `image.tag` in `values.yaml` with the new values.

4. If your private registry requires authentication, create an image-pull secret in the target namespace and set `imagePullSecrets` in `values.yaml` to its name.

</TabItem>
</Tabs>

<h2 id="deploy-app">Deploy app</h2>

Follow these steps to deploy the secure app:

* Install the helm chart. The chart directory now carries your edited `values.yaml`, so no `-f` flag is needed:

 ```bash
 helm install {{deploymentValues.helmChartName}}-release ./{{deploymentValues.helmChartName}} -n <namespace>
 ```

 - Replace `<namespace>` with your target Kubernetes namespace.
 - The helm chart name `{{deploymentValues.helmChartName}}` is automatically used from your selected app.

The deployment process typically takes a few minutes to complete depending on factors like Kubernetes cluster resource availability, private image repository download time etc.

<h2 id="verify-app">Verify app</h2>

Follow these steps to verify deployment:

### Verify deployment status on cluster

1. Check pod status:

 ```bash
 kubectl get pods -n <namespace>
 ```

 The output appears similar to:

 ```
 NAME READY STATUS RESTARTS AGE
 <helm-chart-name>-release-<helm-chart-name>-5dff95cd85-cvk5z 1/1 Running 0 2m
 ```
 
 Replace `<helm-chart-name>` with your app's helm chart name (shown in the prerequisites section earlier in this guide).

 The pod status shows `Running` with `1/1` ready containers.

2. Verify logs for the running pod
 
 ```bash
 kubectl logs -n <namespace> -l app.kubernetes.io/name={{deploymentValues.helmChartName}} --tail=50 -f
 ```
 **Example application logs**: Look for these key log messages that confirm successful deployment:

 * `Uvicorn running on http://0.0.0.0:8000` - Web server started
 * `Workflow engine initialized` - Workflow processing ready
 * `dapr initialized. Status: Running` - Dapr runtime active
 * `Starting worker with task queue: atlan-<package-name>-DEPLOYMENT_NAME` - Worker process started (replace `<package-name>` with your app's package name)
 * `GET /server/ready 200` - Health check endpoint responding

### Verify registration via Atlan UI

Once the App is successfully deployed, it communicates to the Atlan tenant and registers itself. Verify App registration is successful in Atlan:

1. In the same Atlan tenant, navigate to **Workflows** > **Agent**.
2. Look for an entry named `<app_name>-<deployment_name>`, where `<app_name>` matches your selected app (for example, "Oracle" or "Microsoft SQL Server") and `<deployment_name>` is the deployment name you entered when generating the config.
3. Confirm the agent status displays as **Active**.

Agent registration and status takes a couple of minutes to reflect in the Atlan UI.

<h2 id="next-steps">Next steps</h2>

* [Configure workflow execution](https://docs.atlan.com/product/connections/self-deployed-runtime/how-tos/configure-workflow-execution): Set up workflow execution with secret retrieval for your Self-deployed Runtime

---

## Install on Kubernetes - AWS Glue

URL: https://docs.atlan.com/product/connections/self-deployed-runtime/how-tos/install-on-kubernetes
**Connector:** AWS Glue (etl-tools)

> Install an App on Kubernetes using Helm charts, Docker images, and specific configuration

:::info **Did you know?** 
SDR requires additional enablement and licensing. Contact your Atlan representative for details.
:::

:::warning Use the guided install wizard instead
**New Self-Deployed Runtime setups are encouraged to use the [guided install wizard](https://docs.atlan.com/product/connections/self-deployed-runtime/how-tos/install-guided).** It assembles a complete guide tailored to your lifecycle mode, platform, and image procurement on a single page—and it's where new setup options (for example, HTTP proxy and custom CA trust) are documented going forward.

This page is kept for existing users who already reference it and may not include the latest steps.
:::

<h2 id="prerequisites">Prerequisites</h2>

Before you begin, make sure you have:

* `kubectl` installed and configured with administrative access to your target Kubernetes cluster
* Helm version 3.0 or later installed on your deployment machine
* A [Docker Hub Personal Access Token (PAT)](https://start.1password.com/open/i?a=WAVUZSKJO5GMNMVBYWAWECXIUE&v=ouvp3xf5334cxoamyiipzjlewy&i=p76avgzmkkcbftldcuvr5jcof4&h=atlanhq.1password.com) from Atlan
* App-specific helm chart name: `{{deploymentValues.helmChartName}}` 
* Object storage: AWS S3, Google Cloud Storage, or Azure Blob Storage with read/write permissions
* Secret store access: AWS Secret Manager, Azure Key Vault, GCP Secret Manager, HashiCorp Vault, or Kubernetes Secrets with read permissions

:::warning For security reasons, the Docker Hub PAT Token is regenerated on a periodic basis. 
In case the token is embedded in automation scripts or CI/CD pipelines, those jobs may fail. 
Contact your Atlan representative for the latest token.
:::

<h2 id="download-required-files">Download required files</h2>

<h3 id="download-helm-chart">Download Helm chart</h3>

Download the Helm chart for the app:

```bash
helm pull oci://registry-1.docker.io/atlanhq/{{deploymentValues.helmChartName}} --untar
```

This unpacks the chart's `Chart.yaml`, `templates/`, and a default `values.yaml` into `./{{deploymentValues.helmChartName}}/`. You'll replace this default `values.yaml` with your Marketplace copy in the next step.

<h3 id="download-values-yaml">Download values.yaml</h3>

Atlan generates the helm `values.yaml` for your runtime directly from the Marketplace UI, including the OAuth client credentials your runtime uses to authenticate to your tenant.

1. Sign in to your Atlan tenant as an administrator, open **Connector** > **Marketplace**, select the app you want to deploy, and click **Download config for Self-Deployed Runtime** in the right-hand sidebar.

2. In the dialog, keep **New deployment** selected (this mints the OAuth client and full config for a fresh runtime), choose **Kubernetes (Helm)** as the deployment target, and enter a **Deployment name**: a short identifier (lowercase letters, digits, and dashes) that identifies this runtime; the agent in **Workflows > Agent** is named `<app_name>-<deployment_name>`.

3. Click **Generate**. Atlan mints a dedicated OAuth client and produces a `values.yaml` file with:
 - `global.atlanBaseUrl`, `global.clientId`, and `global.clientSecret` already filled in.
 - `image.repository`, `image.tag`, and `name` pinned to the active version for your tenant.
 - `objectstore` and `secretstore` placeholders for you to configure below.

<h3 id="replace-chart-values">Replace chart values.yaml</h3>

Replace the default `values.yaml` inside the unpacked chart with the `values.yaml` you downloaded from the Marketplace.

From this point on, all edits to `values.yaml` must be made inside `./{{deploymentValues.helmChartName}}/`.

<h2 id="modify-values-yaml">Modify values.yaml</h2>

### Object storage

Self-Deployed Runtime needs a store for reading or writing files. Configure the object storage that matches your environment:

:::tip Don't see your preferred object store?
If your preferred object store isn't listed here, [reach out to Atlan support](https://docs.atlan.com/support/submit-request). Support for additional object stores may be available.
:::

<Tabs>
<TabItem value="aws-s3" label="AWS S3" default>

**Required permissions:**

Apply object-level actions to `arn:aws:s3:::BUCKET/*` and the list action to `arn:aws:s3:::BUCKET` in separate IAM statement entries.

| IAM action | Operations covered |
|---|---|
| `s3:GetObject` | GetObject (full and byte-range), HeadObject |
| `s3:PutObject` | PutObject, CreateMultipartUpload, UploadPart, CompleteMultipartUpload |
| `s3:AbortMultipartUpload` | Abort in-flight multipart upload on error (required for streaming write error paths) |
| `s3:DeleteObject` | DeleteObject and DeleteObjects (bulk batch—same IAM action) |
| `s3:ListBucket` | ListObjectsV2—bucket-level permission, not object-level |

```json
{
 "Version": "2012-10-17",
 "Statement": [
 {
 "Effect": "Allow",
 "Action": [
 "s3:GetObject",
 "s3:PutObject",
 "s3:AbortMultipartUpload",
 "s3:DeleteObject"
 ],
 "Resource": "arn:aws:s3:::YOUR-BUCKET/*"
 },
 {
 "Effect": "Allow",
 "Action": "s3:ListBucket",
 "Resource": "arn:aws:s3:::YOUR-BUCKET"
 }
 ]
}
```

**AssumeRole**: when using `assumeRoleArn`, the caller identity additionally needs `sts:AssumeRole` on the target role ARN. The role itself holds the bucket policy described earlier.

**Configure:**

 1. Locate the `objectstore` attribute in `values.yaml`.
 2. Add AWS S3 configuration. For more information, see [AWS S3 Binding Spec](https://docs.dapr.io/reference/components-reference/supported-bindings/s3/).

 ```yaml
 objectstore:
 enabled: true
 spec:
 type: bindings.aws.s3
 version: v1
 metadata:
 - name: accessKey #optional, leave this empty for iam authentication
 value: ""
 - name: secretKey #optional, leave this empty for iam authentication
 value: ""
 - name: bucket #required, name of the bucket where application can write
 value: "<bucket-name>"
 - name: region #required, region of the bucket where application can write
 value: "<bucket-region>"
 - name: forcePathStyle
 value: "true"
 ```

</TabItem>
<TabItem value="gcp-storage" label="Google Cloud Storage">

**Required permissions:**

| IAM permission | Operations covered |
|---|---|
| `storage.objects.get` | GetObject (full and byte-range), object metadata / HeadObject equivalent |
| `storage.objects.create` | PutObject, resumable / streaming write |
| `storage.objects.delete` | DeleteObject (GCS has no native bulk-delete API—`delete_prefix` issues parallel single-object deletes) |
| `storage.objects.list` | ListObjects |

No `storage.buckets.*` permissions are needed. The smallest predefined role that covers all four is **`roles/storage.objectAdmin`** scoped to the bucket. Alternatively, create a custom role with exactly these four permissions.

**Configure:**

 1. Locate the `objectstore` attribute in `values.yaml`.
 2. Add Google Cloud Storage configuration. For more information, see [GCP Storage Bucket binding spec](https://docs.dapr.io/reference/components-reference/supported-bindings/gcpbucket/)

 ```yaml
 objectstore:
 enabled: true
 spec:
 type: bindings.gcp.bucket
 version: v1
 metadata:
 - name: bucket
 value: "your-gcs-bucket-name"
 - name: type
 value: "service_account"
 - name: project_id
 value: "your-gcp-project-id"
 ```

</TabItem>
<TabItem value="azure-blob" label="Azure Blob Storage">

**Required permissions:**

**RBAC**—assign at container or storage-account scope:

| RBAC action | Operations covered |
|---|---|
| `Microsoft.Storage/storageAccounts/blobServices/containers/blobs/read` | GetBlob, GetBlobProperties (HEAD), ListBlobs, byte-range GET |
| `Microsoft.Storage/storageAccounts/blobServices/containers/blobs/write` | PutBlob, PutBlock + PutBlockList (streaming / block write) |
| `Microsoft.Storage/storageAccounts/blobServices/containers/blobs/delete` | DeleteBlob, BlobBatch delete (bulk—up to 256 keys per request) |

The smallest predefined role covering all three is **`Storage Blob Data Contributor`**. `Storage Blob Data Owner` is a superset and is only needed if you additionally require POSIX ACL management on ADLS Gen2.

**SAS token**—minimum permissions at container scope: `r` (read) + `w` (write) + `d` (delete) + `l` (list), that is a container-scoped SAS with **`rwdl`**.

**ADLS Gen2 with POSIX ACLs**: if the storage account has hierarchical namespace enabled and you use ACL-based access control instead of RBAC, the principal needs Execute (`X`) on every parent directory and Read / Write / Delete on the objects in scope. RBAC (`Storage Blob Data Contributor`) is simpler and is recommended unless you have a specific ACL requirement.

**Configure:**

 1. Locate the `objectstore` attribute in `values.yaml`.
 2. Add Azure Blob Storage configuration. For more information, see [Azure Blob Storage binding spec](https://docs.dapr.io/reference/components-reference/supported-bindings/blobstorage/)

 ```yaml
 objectstore:
 enabled: true
 spec:
 type: bindings.azure.blobstorage
 version: v1
 metadata:
 - name: accountName
 value: "your-storage-account-name"
 - name: accountKey
 value: "your-storage-account-key"
 - name: containerName
 value: "your-container-name"
 ```

</TabItem>
</Tabs>

### Secret storage

Self-Deployed Runtime fetches secrets from a secret store to connect to the source systems. The secret store references are used to configure the workflow. Configure the secret store that aligns with your security infrastructure:

:::info Did you know?
Dapr supports additional secret stores which aren't mentioned here. For more information, see [Dapr secret store documentation](https://docs.dapr.io/reference/components-reference/supported-secret-stores/) for other configurations.
:::

:::warning Secret content format and naming
When storing credentials, follow the [secret naming and format requirements](https://docs.atlan.com/product/connections/self-deployed-runtime/how-tos/configure-workflow-execution#secret-content-format).
:::

<Tabs>
<TabItem value="aws-secret-manager" label="AWS Secret Manager" default>
 
 1. Locate the `secretstore` attribute in `values.yaml`.
 2. Add AWS Secret Manager configuration. For more information, see [AWS Secrets Manager](https://docs.dapr.io/reference/components-reference/supported-secret-stores/aws-secret-manager/)

 ```yaml
 secretstore:
 enabled: true
 spec:
 type: secretstores.aws.secretmanager
 version: v1
 metadata:
 - name: region # required, region in which secret is hosted
 value: <secret-region>
 # Needed if IAM authentication is not used
 - name: accessKey
 value: ""
 - name: secretKey
 value: ""
 ```

If you are using IAM role / IRSA authentication, leave `accessKey` and `secretKey` empty.

If you are using an IAM user instead, set:
- `accessKey` to the IAM user's access key ID
- `secretKey` to the IAM user's secret access key

That IAM user must have permission to read the target secret from AWS Secrets Manager:

```json
{
 "Version": "2012-10-17",
 "Statement": [
 {
 "Effect": "Allow",
 "Action": [
 "secretsmanager:GetSecretValue",
 "secretsmanager:DescribeSecret"
 ],
 "Resource": "arn:aws:secretsmanager:<region>:<account-id>:secret:<secret-name>*"
 }
 ]
}
```

:::note
Include the trailing `*` in the secret ARN. AWS appends a random suffix to secret names in the ARN, so omitting it can cause access failures.
:::

</TabItem>
<TabItem value="azure-key-vault" label="Azure Key Vault">

 1. Locate the `secretstore` attribute in `values.yaml`.
 2. Add Azure Key Vault configuration. For more information, see [Azure Key Vault secret store](https://docs.dapr.io/reference/components-reference/supported-secret-stores/azure-keyvault/)

 ```yaml
 secretstore:
 enabled: true
 spec:
 type: secretstores.azure.keyvault
 version: v1
 metadata:
 - name: vaultName
 value: "<your-keyvault-name>"
 - name: azureTenantId
 value: "<your-tenant-id>"
 - name: azureClientId
 value: "<your-client-id>"
 - name: azureClientSecret
 value: "<your-client-secret>"
 - name: azureEnvironment
 value: "AZUREPUBLICCLOUD" # Optional: AZUREPUBLICCLOUD, AZURECHINACLOUD, AZUREUSGOVERNMENTCLOUD, AZUREGERMANCLOUD
 ```
 Azure Key Vault supports multiple authentication methods:
 - **Client Secret**: Use `azureClientSecret` with tenant ID and client ID
 - **Certificate**: Use `azureCertificateFile` instead of client secret
 - **Managed Identity**: Omit authentication fields and use Azure managed identity

 For detailed authentication setup, see the [Authenticating to Azure](https://docs.dapr.io/developing-applications/integrations/azure/azure-authentication/authenticating-azure/) documentation.

</TabItem>
<TabItem value="gcp-secret-manager" label="GCP Secret Manager">

1. Locate the `secretstore` attribute in `values.yaml`.
2. Add Google Cloud Secret Manager configuration. For more information, see [GCP Secret Manager](https://docs.dapr.io/reference/components-reference/supported-secret-stores/gcp-secret-manager/)

 The GCP service account used in this configuration must have the `Secret Manager Secret Accessor` role (`roles/secretmanager.secretAccessor`) on the project where your secrets are stored. The metadata values below come from the service account's JSON key file.

 ```yaml
 secretstore:
 enabled: true
 spec:
 type: secretstores.gcp.secretmanager
 version: v1
 metadata:
 - name: type
 value: "service_account"
 - name: project_id
 value: "<project-id>"
 - name: private_key_id
 value: "<private-key-id>"
 - name: private_key
 value: "<private-key>"
 - name: client_email
 value: "<client-email>"
 - name: client_id
 value: "<client-id>"
 - name: auth_uri
 value: "https://accounts.google.com/o/oauth2/auth"
 - name: token_uri
 value: "https://oauth2.googleapis.com/token"
 - name: auth_provider_x509_cert_url
 value: "https://www.googleapis.com/oauth2/v1/certs"
 - name: client_x509_cert_url
 value: "https://www.googleapis.com/robot/v1/metadata/x509/<client-email>"
 ```

</TabItem>
<TabItem value="hashicorp-vault" label="HashiCorp Vault">

1. Locate the `secretstore` attribute in `values.yaml`.
2. Add HashiCorp Vault configuration. For more information, see [HashiCorp Vault](https://docs.dapr.io/reference/components-reference/supported-secret-stores/hashicorp-vault/)

 ```yaml
 secretstore:
 enabled: true
 spec:
 type: secretstores.hashicorp.vault
 version: v1
 metadata:
 - name: vaultAddr
 value: "[vault_address]" # Optional. Default: "https://127.0.0.1:8200"
 - name: caCert # Optional. This or caPath or caPem
 value: "[ca_cert]"
 - name: caPath # Optional. This or CaCert or caPem
 value: "[path_to_ca_cert_file]"
 - name: caPem # Optional. This or CaCert or CaPath
 value: "[encoded_ca_cert_pem]"
 - name: skipVerify # Optional. Default: false
 value: "[skip_tls_verification]"
 - name: tlsServerName # Optional.
 value: "[tls_config_server_name]"
 - name: vaultTokenMountPath # Required if vaultToken not provided. Path to token file.
 value: "[path_to_file_containing_token]"
 - name: vaultToken # Required if vaultTokenMountPath not provided. Token value.
 value: "[vault_token]"
 - name: vaultKVPrefix # Optional. Default: "dapr"
 value: "[vault_prefix]"
 - name: vaultKVUsePrefix # Optional. default: "true"
 value: "[true/false]"
 - name: enginePath # Optional. default: "secret"
 value: "secret"
 - name: vaultValueType # Optional. default: "map"
 value: "map"
 ```

</TabItem>
<TabItem value="kubernetes-secrets" label="Kubernetes Secrets">

1. Locate the `secretstore` attribute in `values.yaml`.
2. Add Kubernetes native secret storage. For more information, see [Kubernetes secrets](https://docs.dapr.io/reference/components-reference/supported-secret-stores/kubernetes-secret-store/)

 ```yaml
 secretstore:
 enabled: true
 spec:
 type: secretstores.kubernetes
 version: v1
 metadata:
 - name: defaultNamespace
 value: "default" # Optional: Default namespace to retrieve secrets from
 - name: kubeconfigPath
 value: "/path/to/kubeconfig" # Optional: Path to kubeconfig file
 ```
 When Dapr is deployed to a Kubernetes cluster, a secret store with the name `kubernetes` is automatically provisioned. You can use this native Kubernetes secret store with no need to create, deploy or maintain a component configuration file.

</TabItem>
<TabItem value="environment-variable-based" label="Environment Variables">

1. Locate the `secretstore` attribute in `values.yaml`.
2. Add Local environment variables as the spec. For more information, see [Local Environment Variables](https://docs.dapr.io/reference/components-reference/supported-secret-stores/envvar-secret-store/)

 ```yaml
 secretstore:
 enabled: true
 spec:
 type: secretstores.local.env
 version: v1
 ```

</TabItem>
</Tabs>

### Image source

Choose how the cluster pulls the app image. Most installs use Atlan's Docker Hub directly; mirror to a private registry if your organization requires it.

<Tabs>
<TabItem value="docker-hub" label="Public Docker Hub" default>

The chart pulls the app image from Atlan's Docker Hub at runtime. The pod needs a Kubernetes secret containing your Docker Hub PAT to authenticate:

```bash
kubectl create secret docker-registry atlan-docker-secret \
 --docker-server=docker.io \
 --docker-username=YOUR_USERNAME \
 --docker-password=YOUR_PAT_TOKEN \
 -n <namespace>
```

- Replace `YOUR_USERNAME` with the Docker Hub username provided by Atlan.
- Replace `YOUR_PAT_TOKEN` with the Personal Access Token (PAT) provided by Atlan.
- Replace `<namespace>` with the namespace you need to install the chart into. The secret and the release must live in the same namespace, or the pod fails with `ImagePullBackOff`.

The downloaded `values.yaml` already references this secret under `imagePullSecrets`. If you use a different secret name, update that field in the file.

</TabItem>
<TabItem value="private-registry" label="Private image repo">

Mirror the Atlan image to your enterprise registry and update `values.yaml` to point at it.

1. Authenticate with Docker Hub using the PAT from Atlan, then pull the source image. The image and tag come from `image.repository` and `image.tag` in the downloaded `values.yaml`:

 ```bash
 docker login -u atlanhq
 # When prompted for password, enter the PAT provided by Atlan
 docker pull <image.repository>:<image.tag>
 ```

2. Push the image to your enterprise's registry. Note down the new repository name and image tag.

3. Update `image.repository` and `image.tag` in `values.yaml` with the new values.

4. If your private registry requires authentication, create an image-pull secret in the target namespace and set `imagePullSecrets` in `values.yaml` to its name.

</TabItem>
</Tabs>

<h2 id="deploy-app">Deploy app</h2>

Follow these steps to deploy the secure app:

* Install the helm chart. The chart directory now carries your edited `values.yaml`, so no `-f` flag is needed:

 ```bash
 helm install {{deploymentValues.helmChartName}}-release ./{{deploymentValues.helmChartName}} -n <namespace>
 ```

 - Replace `<namespace>` with your target Kubernetes namespace.
 - The helm chart name `{{deploymentValues.helmChartName}}` is automatically used from your selected app.

The deployment process typically takes a few minutes to complete depending on factors like Kubernetes cluster resource availability, private image repository download time etc.

<h2 id="verify-app">Verify app</h2>

Follow these steps to verify deployment:

### Verify deployment status on cluster

1. Check pod status:

 ```bash
 kubectl get pods -n <namespace>
 ```

 The output appears similar to:

 ```
 NAME READY STATUS RESTARTS AGE
 <helm-chart-name>-release-<helm-chart-name>-5dff95cd85-cvk5z 1/1 Running 0 2m
 ```
 
 Replace `<helm-chart-name>` with your app's helm chart name (shown in the prerequisites section earlier in this guide).

 The pod status shows `Running` with `1/1` ready containers.

2. Verify logs for the running pod
 
 ```bash
 kubectl logs -n <namespace> -l app.kubernetes.io/name={{deploymentValues.helmChartName}} --tail=50 -f
 ```
 **Example application logs**: Look for these key log messages that confirm successful deployment:

 * `Uvicorn running on http://0.0.0.0:8000` - Web server started
 * `Workflow engine initialized` - Workflow processing ready
 * `dapr initialized. Status: Running` - Dapr runtime active
 * `Starting worker with task queue: atlan-<package-name>-DEPLOYMENT_NAME` - Worker process started (replace `<package-name>` with your app's package name)
 * `GET /server/ready 200` - Health check endpoint responding

### Verify registration via Atlan UI

Once the App is successfully deployed, it communicates to the Atlan tenant and registers itself. Verify App registration is successful in Atlan:

1. In the same Atlan tenant, navigate to **Workflows** > **Agent**.
2. Look for an entry named `<app_name>-<deployment_name>`, where `<app_name>` matches your selected app (for example, "Oracle" or "Microsoft SQL Server") and `<deployment_name>` is the deployment name you entered when generating the config.
3. Confirm the agent status displays as **Active**.

Agent registration and status takes a couple of minutes to reflect in the Atlan UI.

<h2 id="next-steps">Next steps</h2>

* [Configure workflow execution](https://docs.atlan.com/product/connections/self-deployed-runtime/how-tos/configure-workflow-execution): Set up workflow execution with secret retrieval for your Self-deployed Runtime

---

## Install on Kubernetes - Apache Kafka

URL: https://docs.atlan.com/product/connections/self-deployed-runtime/how-tos/install-on-kubernetes
**Connector:** Apache Kafka (messaging)

> Install an App on Kubernetes using Helm charts, Docker images, and specific configuration

:::info **Did you know?** 
SDR requires additional enablement and licensing. Contact your Atlan representative for details.
:::

:::warning Use the guided install wizard instead
**New Self-Deployed Runtime setups are encouraged to use the [guided install wizard](https://docs.atlan.com/product/connections/self-deployed-runtime/how-tos/install-guided).** It assembles a complete guide tailored to your lifecycle mode, platform, and image procurement on a single page—and it's where new setup options (for example, HTTP proxy and custom CA trust) are documented going forward.

This page is kept for existing users who already reference it and may not include the latest steps.
:::

<h2 id="prerequisites">Prerequisites</h2>

Before you begin, make sure you have:

* `kubectl` installed and configured with administrative access to your target Kubernetes cluster
* Helm version 3.0 or later installed on your deployment machine
* A [Docker Hub Personal Access Token (PAT)](https://start.1password.com/open/i?a=WAVUZSKJO5GMNMVBYWAWECXIUE&v=ouvp3xf5334cxoamyiipzjlewy&i=p76avgzmkkcbftldcuvr5jcof4&h=atlanhq.1password.com) from Atlan
* App-specific helm chart name: `{{deploymentValues.helmChartName}}` 
* Object storage: AWS S3, Google Cloud Storage, or Azure Blob Storage with read/write permissions
* Secret store access: AWS Secret Manager, Azure Key Vault, GCP Secret Manager, HashiCorp Vault, or Kubernetes Secrets with read permissions

:::warning For security reasons, the Docker Hub PAT Token is regenerated on a periodic basis. 
In case the token is embedded in automation scripts or CI/CD pipelines, those jobs may fail. 
Contact your Atlan representative for the latest token.
:::

<h2 id="download-required-files">Download required files</h2>

<h3 id="download-helm-chart">Download Helm chart</h3>

Download the Helm chart for the app:

```bash
helm pull oci://registry-1.docker.io/atlanhq/{{deploymentValues.helmChartName}} --untar
```

This unpacks the chart's `Chart.yaml`, `templates/`, and a default `values.yaml` into `./{{deploymentValues.helmChartName}}/`. You'll replace this default `values.yaml` with your Marketplace copy in the next step.

<h3 id="download-values-yaml">Download values.yaml</h3>

Atlan generates the helm `values.yaml` for your runtime directly from the Marketplace UI, including the OAuth client credentials your runtime uses to authenticate to your tenant.

1. Sign in to your Atlan tenant as an administrator, open **Connector** > **Marketplace**, select the app you want to deploy, and click **Download config for Self-Deployed Runtime** in the right-hand sidebar.

2. In the dialog, keep **New deployment** selected (this mints the OAuth client and full config for a fresh runtime), choose **Kubernetes (Helm)** as the deployment target, and enter a **Deployment name**: a short identifier (lowercase letters, digits, and dashes) that identifies this runtime; the agent in **Workflows > Agent** is named `<app_name>-<deployment_name>`.

3. Click **Generate**. Atlan mints a dedicated OAuth client and produces a `values.yaml` file with:
 - `global.atlanBaseUrl`, `global.clientId`, and `global.clientSecret` already filled in.
 - `image.repository`, `image.tag`, and `name` pinned to the active version for your tenant.
 - `objectstore` and `secretstore` placeholders for you to configure below.

<h3 id="replace-chart-values">Replace chart values.yaml</h3>

Replace the default `values.yaml` inside the unpacked chart with the `values.yaml` you downloaded from the Marketplace.

From this point on, all edits to `values.yaml` must be made inside `./{{deploymentValues.helmChartName}}/`.

<h2 id="modify-values-yaml">Modify values.yaml</h2>

### Object storage

Self-Deployed Runtime needs a store for reading or writing files. Configure the object storage that matches your environment:

:::tip Don't see your preferred object store?
If your preferred object store isn't listed here, [reach out to Atlan support](https://docs.atlan.com/support/submit-request). Support for additional object stores may be available.
:::

<Tabs>
<TabItem value="aws-s3" label="AWS S3" default>

**Required permissions:**

Apply object-level actions to `arn:aws:s3:::BUCKET/*` and the list action to `arn:aws:s3:::BUCKET` in separate IAM statement entries.

| IAM action | Operations covered |
|---|---|
| `s3:GetObject` | GetObject (full and byte-range), HeadObject |
| `s3:PutObject` | PutObject, CreateMultipartUpload, UploadPart, CompleteMultipartUpload |
| `s3:AbortMultipartUpload` | Abort in-flight multipart upload on error (required for streaming write error paths) |
| `s3:DeleteObject` | DeleteObject and DeleteObjects (bulk batch—same IAM action) |
| `s3:ListBucket` | ListObjectsV2—bucket-level permission, not object-level |

```json
{
 "Version": "2012-10-17",
 "Statement": [
 {
 "Effect": "Allow",
 "Action": [
 "s3:GetObject",
 "s3:PutObject",
 "s3:AbortMultipartUpload",
 "s3:DeleteObject"
 ],
 "Resource": "arn:aws:s3:::YOUR-BUCKET/*"
 },
 {
 "Effect": "Allow",
 "Action": "s3:ListBucket",
 "Resource": "arn:aws:s3:::YOUR-BUCKET"
 }
 ]
}
```

**AssumeRole**: when using `assumeRoleArn`, the caller identity additionally needs `sts:AssumeRole` on the target role ARN. The role itself holds the bucket policy described earlier.

**Configure:**

 1. Locate the `objectstore` attribute in `values.yaml`.
 2. Add AWS S3 configuration. For more information, see [AWS S3 Binding Spec](https://docs.dapr.io/reference/components-reference/supported-bindings/s3/).

 ```yaml
 objectstore:
 enabled: true
 spec:
 type: bindings.aws.s3
 version: v1
 metadata:
 - name: accessKey #optional, leave this empty for iam authentication
 value: ""
 - name: secretKey #optional, leave this empty for iam authentication
 value: ""
 - name: bucket #required, name of the bucket where application can write
 value: "<bucket-name>"
 - name: region #required, region of the bucket where application can write
 value: "<bucket-region>"
 - name: forcePathStyle
 value: "true"
 ```

</TabItem>
<TabItem value="gcp-storage" label="Google Cloud Storage">

**Required permissions:**

| IAM permission | Operations covered |
|---|---|
| `storage.objects.get` | GetObject (full and byte-range), object metadata / HeadObject equivalent |
| `storage.objects.create` | PutObject, resumable / streaming write |
| `storage.objects.delete` | DeleteObject (GCS has no native bulk-delete API—`delete_prefix` issues parallel single-object deletes) |
| `storage.objects.list` | ListObjects |

No `storage.buckets.*` permissions are needed. The smallest predefined role that covers all four is **`roles/storage.objectAdmin`** scoped to the bucket. Alternatively, create a custom role with exactly these four permissions.

**Configure:**

 1. Locate the `objectstore` attribute in `values.yaml`.
 2. Add Google Cloud Storage configuration. For more information, see [GCP Storage Bucket binding spec](https://docs.dapr.io/reference/components-reference/supported-bindings/gcpbucket/)

 ```yaml
 objectstore:
 enabled: true
 spec:
 type: bindings.gcp.bucket
 version: v1
 metadata:
 - name: bucket
 value: "your-gcs-bucket-name"
 - name: type
 value: "service_account"
 - name: project_id
 value: "your-gcp-project-id"
 ```

</TabItem>
<TabItem value="azure-blob" label="Azure Blob Storage">

**Required permissions:**

**RBAC**—assign at container or storage-account scope:

| RBAC action | Operations covered |
|---|---|
| `Microsoft.Storage/storageAccounts/blobServices/containers/blobs/read` | GetBlob, GetBlobProperties (HEAD), ListBlobs, byte-range GET |
| `Microsoft.Storage/storageAccounts/blobServices/containers/blobs/write` | PutBlob, PutBlock + PutBlockList (streaming / block write) |
| `Microsoft.Storage/storageAccounts/blobServices/containers/blobs/delete` | DeleteBlob, BlobBatch delete (bulk—up to 256 keys per request) |

The smallest predefined role covering all three is **`Storage Blob Data Contributor`**. `Storage Blob Data Owner` is a superset and is only needed if you additionally require POSIX ACL management on ADLS Gen2.

**SAS token**—minimum permissions at container scope: `r` (read) + `w` (write) + `d` (delete) + `l` (list), that is a container-scoped SAS with **`rwdl`**.

**ADLS Gen2 with POSIX ACLs**: if the storage account has hierarchical namespace enabled and you use ACL-based access control instead of RBAC, the principal needs Execute (`X`) on every parent directory and Read / Write / Delete on the objects in scope. RBAC (`Storage Blob Data Contributor`) is simpler and is recommended unless you have a specific ACL requirement.

**Configure:**

 1. Locate the `objectstore` attribute in `values.yaml`.
 2. Add Azure Blob Storage configuration. For more information, see [Azure Blob Storage binding spec](https://docs.dapr.io/reference/components-reference/supported-bindings/blobstorage/)

 ```yaml
 objectstore:
 enabled: true
 spec:
 type: bindings.azure.blobstorage
 version: v1
 metadata:
 - name: accountName
 value: "your-storage-account-name"
 - name: accountKey
 value: "your-storage-account-key"
 - name: containerName
 value: "your-container-name"
 ```

</TabItem>
</Tabs>

### Secret storage

Self-Deployed Runtime fetches secrets from a secret store to connect to the source systems. The secret store references are used to configure the workflow. Configure the secret store that aligns with your security infrastructure:

:::info Did you know?
Dapr supports additional secret stores which aren't mentioned here. For more information, see [Dapr secret store documentation](https://docs.dapr.io/reference/components-reference/supported-secret-stores/) for other configurations.
:::

:::warning Secret content format and naming
When storing credentials, follow the [secret naming and format requirements](https://docs.atlan.com/product/connections/self-deployed-runtime/how-tos/configure-workflow-execution#secret-content-format).
:::

<Tabs>
<TabItem value="aws-secret-manager" label="AWS Secret Manager" default>
 
 1. Locate the `secretstore` attribute in `values.yaml`.
 2. Add AWS Secret Manager configuration. For more information, see [AWS Secrets Manager](https://docs.dapr.io/reference/components-reference/supported-secret-stores/aws-secret-manager/)

 ```yaml
 secretstore:
 enabled: true
 spec:
 type: secretstores.aws.secretmanager
 version: v1
 metadata:
 - name: region # required, region in which secret is hosted
 value: <secret-region>
 # Needed if IAM authentication is not used
 - name: accessKey
 value: ""
 - name: secretKey
 value: ""
 ```

If you are using IAM role / IRSA authentication, leave `accessKey` and `secretKey` empty.

If you are using an IAM user instead, set:
- `accessKey` to the IAM user's access key ID
- `secretKey` to the IAM user's secret access key

That IAM user must have permission to read the target secret from AWS Secrets Manager:

```json
{
 "Version": "2012-10-17",
 "Statement": [
 {
 "Effect": "Allow",
 "Action": [
 "secretsmanager:GetSecretValue",
 "secretsmanager:DescribeSecret"
 ],
 "Resource": "arn:aws:secretsmanager:<region>:<account-id>:secret:<secret-name>*"
 }
 ]
}
```

:::note
Include the trailing `*` in the secret ARN. AWS appends a random suffix to secret names in the ARN, so omitting it can cause access failures.
:::

</TabItem>
<TabItem value="azure-key-vault" label="Azure Key Vault">

 1. Locate the `secretstore` attribute in `values.yaml`.
 2. Add Azure Key Vault configuration. For more information, see [Azure Key Vault secret store](https://docs.dapr.io/reference/components-reference/supported-secret-stores/azure-keyvault/)

 ```yaml
 secretstore:
 enabled: true
 spec:
 type: secretstores.azure.keyvault
 version: v1
 metadata:
 - name: vaultName
 value: "<your-keyvault-name>"
 - name: azureTenantId
 value: "<your-tenant-id>"
 - name: azureClientId
 value: "<your-client-id>"
 - name: azureClientSecret
 value: "<your-client-secret>"
 - name: azureEnvironment
 value: "AZUREPUBLICCLOUD" # Optional: AZUREPUBLICCLOUD, AZURECHINACLOUD, AZUREUSGOVERNMENTCLOUD, AZUREGERMANCLOUD
 ```
 Azure Key Vault supports multiple authentication methods:
 - **Client Secret**: Use `azureClientSecret` with tenant ID and client ID
 - **Certificate**: Use `azureCertificateFile` instead of client secret
 - **Managed Identity**: Omit authentication fields and use Azure managed identity

 For detailed authentication setup, see the [Authenticating to Azure](https://docs.dapr.io/developing-applications/integrations/azure/azure-authentication/authenticating-azure/) documentation.

</TabItem>
<TabItem value="gcp-secret-manager" label="GCP Secret Manager">

1. Locate the `secretstore` attribute in `values.yaml`.
2. Add Google Cloud Secret Manager configuration. For more information, see [GCP Secret Manager](https://docs.dapr.io/reference/components-reference/supported-secret-stores/gcp-secret-manager/)

 The GCP service account used in this configuration must have the `Secret Manager Secret Accessor` role (`roles/secretmanager.secretAccessor`) on the project where your secrets are stored. The metadata values below come from the service account's JSON key file.

 ```yaml
 secretstore:
 enabled: true
 spec:
 type: secretstores.gcp.secretmanager
 version: v1
 metadata:
 - name: type
 value: "service_account"
 - name: project_id
 value: "<project-id>"
 - name: private_key_id
 value: "<private-key-id>"
 - name: private_key
 value: "<private-key>"
 - name: client_email
 value: "<client-email>"
 - name: client_id
 value: "<client-id>"
 - name: auth_uri
 value: "https://accounts.google.com/o/oauth2/auth"
 - name: token_uri
 value: "https://oauth2.googleapis.com/token"
 - name: auth_provider_x509_cert_url
 value: "https://www.googleapis.com/oauth2/v1/certs"
 - name: client_x509_cert_url
 value: "https://www.googleapis.com/robot/v1/metadata/x509/<client-email>"
 ```

</TabItem>
<TabItem value="hashicorp-vault" label="HashiCorp Vault">

1. Locate the `secretstore` attribute in `values.yaml`.
2. Add HashiCorp Vault configuration. For more information, see [HashiCorp Vault](https://docs.dapr.io/reference/components-reference/supported-secret-stores/hashicorp-vault/)

 ```yaml
 secretstore:
 enabled: true
 spec:
 type: secretstores.hashicorp.vault
 version: v1
 metadata:
 - name: vaultAddr
 value: "[vault_address]" # Optional. Default: "https://127.0.0.1:8200"
 - name: caCert # Optional. This or caPath or caPem
 value: "[ca_cert]"
 - name: caPath # Optional. This or CaCert or caPem
 value: "[path_to_ca_cert_file]"
 - name: caPem # Optional. This or CaCert or CaPath
 value: "[encoded_ca_cert_pem]"
 - name: skipVerify # Optional. Default: false
 value: "[skip_tls_verification]"
 - name: tlsServerName # Optional.
 value: "[tls_config_server_name]"
 - name: vaultTokenMountPath # Required if vaultToken not provided. Path to token file.
 value: "[path_to_file_containing_token]"
 - name: vaultToken # Required if vaultTokenMountPath not provided. Token value.
 value: "[vault_token]"
 - name: vaultKVPrefix # Optional. Default: "dapr"
 value: "[vault_prefix]"
 - name: vaultKVUsePrefix # Optional. default: "true"
 value: "[true/false]"
 - name: enginePath # Optional. default: "secret"
 value: "secret"
 - name: vaultValueType # Optional. default: "map"
 value: "map"
 ```

</TabItem>
<TabItem value="kubernetes-secrets" label="Kubernetes Secrets">

1. Locate the `secretstore` attribute in `values.yaml`.
2. Add Kubernetes native secret storage. For more information, see [Kubernetes secrets](https://docs.dapr.io/reference/components-reference/supported-secret-stores/kubernetes-secret-store/)

 ```yaml
 secretstore:
 enabled: true
 spec:
 type: secretstores.kubernetes
 version: v1
 metadata:
 - name: defaultNamespace
 value: "default" # Optional: Default namespace to retrieve secrets from
 - name: kubeconfigPath
 value: "/path/to/kubeconfig" # Optional: Path to kubeconfig file
 ```
 When Dapr is deployed to a Kubernetes cluster, a secret store with the name `kubernetes` is automatically provisioned. You can use this native Kubernetes secret store with no need to create, deploy or maintain a component configuration file.

</TabItem>
<TabItem value="environment-variable-based" label="Environment Variables">

1. Locate the `secretstore` attribute in `values.yaml`.
2. Add Local environment variables as the spec. For more information, see [Local Environment Variables](https://docs.dapr.io/reference/components-reference/supported-secret-stores/envvar-secret-store/)

 ```yaml
 secretstore:
 enabled: true
 spec:
 type: secretstores.local.env
 version: v1
 ```

</TabItem>
</Tabs>

### Image source

Choose how the cluster pulls the app image. Most installs use Atlan's Docker Hub directly; mirror to a private registry if your organization requires it.

<Tabs>
<TabItem value="docker-hub" label="Public Docker Hub" default>

The chart pulls the app image from Atlan's Docker Hub at runtime. The pod needs a Kubernetes secret containing your Docker Hub PAT to authenticate:

```bash
kubectl create secret docker-registry atlan-docker-secret \
 --docker-server=docker.io \
 --docker-username=YOUR_USERNAME \
 --docker-password=YOUR_PAT_TOKEN \
 -n <namespace>
```

- Replace `YOUR_USERNAME` with the Docker Hub username provided by Atlan.
- Replace `YOUR_PAT_TOKEN` with the Personal Access Token (PAT) provided by Atlan.
- Replace `<namespace>` with the namespace you need to install the chart into. The secret and the release must live in the same namespace, or the pod fails with `ImagePullBackOff`.

The downloaded `values.yaml` already references this secret under `imagePullSecrets`. If you use a different secret name, update that field in the file.

</TabItem>
<TabItem value="private-registry" label="Private image repo">

Mirror the Atlan image to your enterprise registry and update `values.yaml` to point at it.

1. Authenticate with Docker Hub using the PAT from Atlan, then pull the source image. The image and tag come from `image.repository` and `image.tag` in the downloaded `values.yaml`:

 ```bash
 docker login -u atlanhq
 # When prompted for password, enter the PAT provided by Atlan
 docker pull <image.repository>:<image.tag>
 ```

2. Push the image to your enterprise's registry. Note down the new repository name and image tag.

3. Update `image.repository` and `image.tag` in `values.yaml` with the new values.

4. If your private registry requires authentication, create an image-pull secret in the target namespace and set `imagePullSecrets` in `values.yaml` to its name.

</TabItem>
</Tabs>

<h2 id="deploy-app">Deploy app</h2>

Follow these steps to deploy the secure app:

* Install the helm chart. The chart directory now carries your edited `values.yaml`, so no `-f` flag is needed:

 ```bash
 helm install {{deploymentValues.helmChartName}}-release ./{{deploymentValues.helmChartName}} -n <namespace>
 ```

 - Replace `<namespace>` with your target Kubernetes namespace.
 - The helm chart name `{{deploymentValues.helmChartName}}` is automatically used from your selected app.

The deployment process typically takes a few minutes to complete depending on factors like Kubernetes cluster resource availability, private image repository download time etc.

<h2 id="verify-app">Verify app</h2>

Follow these steps to verify deployment:

### Verify deployment status on cluster

1. Check pod status:

 ```bash
 kubectl get pods -n <namespace>
 ```

 The output appears similar to:

 ```
 NAME READY STATUS RESTARTS AGE
 <helm-chart-name>-release-<helm-chart-name>-5dff95cd85-cvk5z 1/1 Running 0 2m
 ```
 
 Replace `<helm-chart-name>` with your app's helm chart name (shown in the prerequisites section earlier in this guide).

 The pod status shows `Running` with `1/1` ready containers.

2. Verify logs for the running pod
 
 ```bash
 kubectl logs -n <namespace> -l app.kubernetes.io/name={{deploymentValues.helmChartName}} --tail=50 -f
 ```
 **Example application logs**: Look for these key log messages that confirm successful deployment:

 * `Uvicorn running on http://0.0.0.0:8000` - Web server started
 * `Workflow engine initialized` - Workflow processing ready
 * `dapr initialized. Status: Running` - Dapr runtime active
 * `Starting worker with task queue: atlan-<package-name>-DEPLOYMENT_NAME` - Worker process started (replace `<package-name>` with your app's package name)
 * `GET /server/ready 200` - Health check endpoint responding

### Verify registration via Atlan UI

Once the App is successfully deployed, it communicates to the Atlan tenant and registers itself. Verify App registration is successful in Atlan:

1. In the same Atlan tenant, navigate to **Workflows** > **Agent**.
2. Look for an entry named `<app_name>-<deployment_name>`, where `<app_name>` matches your selected app (for example, "Oracle" or "Microsoft SQL Server") and `<deployment_name>` is the deployment name you entered when generating the config.
3. Confirm the agent status displays as **Active**.

Agent registration and status takes a couple of minutes to reflect in the Atlan UI.

<h2 id="next-steps">Next steps</h2>

* [Configure workflow execution](https://docs.atlan.com/product/connections/self-deployed-runtime/how-tos/configure-workflow-execution): Set up workflow execution with secret retrieval for your Self-deployed Runtime

---

## Install on Kubernetes - Confluent Kafka

URL: https://docs.atlan.com/product/connections/self-deployed-runtime/how-tos/install-on-kubernetes
**Connector:** Confluent Kafka (messaging)

> Install an App on Kubernetes using Helm charts, Docker images, and specific configuration

:::info **Did you know?** 
SDR requires additional enablement and licensing. Contact your Atlan representative for details.
:::

:::warning Use the guided install wizard instead
**New Self-Deployed Runtime setups are encouraged to use the [guided install wizard](https://docs.atlan.com/product/connections/self-deployed-runtime/how-tos/install-guided).** It assembles a complete guide tailored to your lifecycle mode, platform, and image procurement on a single page—and it's where new setup options (for example, HTTP proxy and custom CA trust) are documented going forward.

This page is kept for existing users who already reference it and may not include the latest steps.
:::

<h2 id="prerequisites">Prerequisites</h2>

Before you begin, make sure you have:

* `kubectl` installed and configured with administrative access to your target Kubernetes cluster
* Helm version 3.0 or later installed on your deployment machine
* A [Docker Hub Personal Access Token (PAT)](https://start.1password.com/open/i?a=WAVUZSKJO5GMNMVBYWAWECXIUE&v=ouvp3xf5334cxoamyiipzjlewy&i=p76avgzmkkcbftldcuvr5jcof4&h=atlanhq.1password.com) from Atlan
* App-specific helm chart name: `{{deploymentValues.helmChartName}}` 
* Object storage: AWS S3, Google Cloud Storage, or Azure Blob Storage with read/write permissions
* Secret store access: AWS Secret Manager, Azure Key Vault, GCP Secret Manager, HashiCorp Vault, or Kubernetes Secrets with read permissions

:::warning For security reasons, the Docker Hub PAT Token is regenerated on a periodic basis. 
In case the token is embedded in automation scripts or CI/CD pipelines, those jobs may fail. 
Contact your Atlan representative for the latest token.
:::

<h2 id="download-required-files">Download required files</h2>

<h3 id="download-helm-chart">Download Helm chart</h3>

Download the Helm chart for the app:

```bash
helm pull oci://registry-1.docker.io/atlanhq/{{deploymentValues.helmChartName}} --untar
```

This unpacks the chart's `Chart.yaml`, `templates/`, and a default `values.yaml` into `./{{deploymentValues.helmChartName}}/`. You'll replace this default `values.yaml` with your Marketplace copy in the next step.

<h3 id="download-values-yaml">Download values.yaml</h3>

Atlan generates the helm `values.yaml` for your runtime directly from the Marketplace UI, including the OAuth client credentials your runtime uses to authenticate to your tenant.

1. Sign in to your Atlan tenant as an administrator, open **Connector** > **Marketplace**, select the app you want to deploy, and click **Download config for Self-Deployed Runtime** in the right-hand sidebar.

2. In the dialog, keep **New deployment** selected (this mints the OAuth client and full config for a fresh runtime), choose **Kubernetes (Helm)** as the deployment target, and enter a **Deployment name**: a short identifier (lowercase letters, digits, and dashes) that identifies this runtime; the agent in **Workflows > Agent** is named `<app_name>-<deployment_name>`.

3. Click **Generate**. Atlan mints a dedicated OAuth client and produces a `values.yaml` file with:
 - `global.atlanBaseUrl`, `global.clientId`, and `global.clientSecret` already filled in.
 - `image.repository`, `image.tag`, and `name` pinned to the active version for your tenant.
 - `objectstore` and `secretstore` placeholders for you to configure below.

<h3 id="replace-chart-values">Replace chart values.yaml</h3>

Replace the default `values.yaml` inside the unpacked chart with the `values.yaml` you downloaded from the Marketplace.

From this point on, all edits to `values.yaml` must be made inside `./{{deploymentValues.helmChartName}}/`.

<h2 id="modify-values-yaml">Modify values.yaml</h2>

### Object storage

Self-Deployed Runtime needs a store for reading or writing files. Configure the object storage that matches your environment:

:::tip Don't see your preferred object store?
If your preferred object store isn't listed here, [reach out to Atlan support](https://docs.atlan.com/support/submit-request). Support for additional object stores may be available.
:::

<Tabs>
<TabItem value="aws-s3" label="AWS S3" default>

**Required permissions:**

Apply object-level actions to `arn:aws:s3:::BUCKET/*` and the list action to `arn:aws:s3:::BUCKET` in separate IAM statement entries.

| IAM action | Operations covered |
|---|---|
| `s3:GetObject` | GetObject (full and byte-range), HeadObject |
| `s3:PutObject` | PutObject, CreateMultipartUpload, UploadPart, CompleteMultipartUpload |
| `s3:AbortMultipartUpload` | Abort in-flight multipart upload on error (required for streaming write error paths) |
| `s3:DeleteObject` | DeleteObject and DeleteObjects (bulk batch—same IAM action) |
| `s3:ListBucket` | ListObjectsV2—bucket-level permission, not object-level |

```json
{
 "Version": "2012-10-17",
 "Statement": [
 {
 "Effect": "Allow",
 "Action": [
 "s3:GetObject",
 "s3:PutObject",
 "s3:AbortMultipartUpload",
 "s3:DeleteObject"
 ],
 "Resource": "arn:aws:s3:::YOUR-BUCKET/*"
 },
 {
 "Effect": "Allow",
 "Action": "s3:ListBucket",
 "Resource": "arn:aws:s3:::YOUR-BUCKET"
 }
 ]
}
```

**AssumeRole**: when using `assumeRoleArn`, the caller identity additionally needs `sts:AssumeRole` on the target role ARN. The role itself holds the bucket policy described earlier.

**Configure:**

 1. Locate the `objectstore` attribute in `values.yaml`.
 2. Add AWS S3 configuration. For more information, see [AWS S3 Binding Spec](https://docs.dapr.io/reference/components-reference/supported-bindings/s3/).

 ```yaml
 objectstore:
 enabled: true
 spec:
 type: bindings.aws.s3
 version: v1
 metadata:
 - name: accessKey #optional, leave this empty for iam authentication
 value: ""
 - name: secretKey #optional, leave this empty for iam authentication
 value: ""
 - name: bucket #required, name of the bucket where application can write
 value: "<bucket-name>"
 - name: region #required, region of the bucket where application can write
 value: "<bucket-region>"
 - name: forcePathStyle
 value: "true"
 ```

</TabItem>
<TabItem value="gcp-storage" label="Google Cloud Storage">

**Required permissions:**

| IAM permission | Operations covered |
|---|---|
| `storage.objects.get` | GetObject (full and byte-range), object metadata / HeadObject equivalent |
| `storage.objects.create` | PutObject, resumable / streaming write |
| `storage.objects.delete` | DeleteObject (GCS has no native bulk-delete API—`delete_prefix` issues parallel single-object deletes) |
| `storage.objects.list` | ListObjects |

No `storage.buckets.*` permissions are needed. The smallest predefined role that covers all four is **`roles/storage.objectAdmin`** scoped to the bucket. Alternatively, create a custom role with exactly these four permissions.

**Configure:**

 1. Locate the `objectstore` attribute in `values.yaml`.
 2. Add Google Cloud Storage configuration. For more information, see [GCP Storage Bucket binding spec](https://docs.dapr.io/reference/components-reference/supported-bindings/gcpbucket/)

 ```yaml
 objectstore:
 enabled: true
 spec:
 type: bindings.gcp.bucket
 version: v1
 metadata:
 - name: bucket
 value: "your-gcs-bucket-name"
 - name: type
 value: "service_account"
 - name: project_id
 value: "your-gcp-project-id"
 ```

</TabItem>
<TabItem value="azure-blob" label="Azure Blob Storage">

**Required permissions:**

**RBAC**—assign at container or storage-account scope:

| RBAC action | Operations covered |
|---|---|
| `Microsoft.Storage/storageAccounts/blobServices/containers/blobs/read` | GetBlob, GetBlobProperties (HEAD), ListBlobs, byte-range GET |
| `Microsoft.Storage/storageAccounts/blobServices/containers/blobs/write` | PutBlob, PutBlock + PutBlockList (streaming / block write) |
| `Microsoft.Storage/storageAccounts/blobServices/containers/blobs/delete` | DeleteBlob, BlobBatch delete (bulk—up to 256 keys per request) |

The smallest predefined role covering all three is **`Storage Blob Data Contributor`**. `Storage Blob Data Owner` is a superset and is only needed if you additionally require POSIX ACL management on ADLS Gen2.

**SAS token**—minimum permissions at container scope: `r` (read) + `w` (write) + `d` (delete) + `l` (list), that is a container-scoped SAS with **`rwdl`**.

**ADLS Gen2 with POSIX ACLs**: if the storage account has hierarchical namespace enabled and you use ACL-based access control instead of RBAC, the principal needs Execute (`X`) on every parent directory and Read / Write / Delete on the objects in scope. RBAC (`Storage Blob Data Contributor`) is simpler and is recommended unless you have a specific ACL requirement.

**Configure:**

 1. Locate the `objectstore` attribute in `values.yaml`.
 2. Add Azure Blob Storage configuration. For more information, see [Azure Blob Storage binding spec](https://docs.dapr.io/reference/components-reference/supported-bindings/blobstorage/)

 ```yaml
 objectstore:
 enabled: true
 spec:
 type: bindings.azure.blobstorage
 version: v1
 metadata:
 - name: accountName
 value: "your-storage-account-name"
 - name: accountKey
 value: "your-storage-account-key"
 - name: containerName
 value: "your-container-name"
 ```

</TabItem>
</Tabs>

### Secret storage

Self-Deployed Runtime fetches secrets from a secret store to connect to the source systems. The secret store references are used to configure the workflow. Configure the secret store that aligns with your security infrastructure:

:::info Did you know?
Dapr supports additional secret stores which aren't mentioned here. For more information, see [Dapr secret store documentation](https://docs.dapr.io/reference/components-reference/supported-secret-stores/) for other configurations.
:::

:::warning Secret content format and naming
When storing credentials, follow the [secret naming and format requirements](https://docs.atlan.com/product/connections/self-deployed-runtime/how-tos/configure-workflow-execution#secret-content-format).
:::

<Tabs>
<TabItem value="aws-secret-manager" label="AWS Secret Manager" default>
 
 1. Locate the `secretstore` attribute in `values.yaml`.
 2. Add AWS Secret Manager configuration. For more information, see [AWS Secrets Manager](https://docs.dapr.io/reference/components-reference/supported-secret-stores/aws-secret-manager/)

 ```yaml
 secretstore:
 enabled: true
 spec:
 type: secretstores.aws.secretmanager
 version: v1
 metadata:
 - name: region # required, region in which secret is hosted
 value: <secret-region>
 # Needed if IAM authentication is not used
 - name: accessKey
 value: ""
 - name: secretKey
 value: ""
 ```

If you are using IAM role / IRSA authentication, leave `accessKey` and `secretKey` empty.

If you are using an IAM user instead, set:
- `accessKey` to the IAM user's access key ID
- `secretKey` to the IAM user's secret access key

That IAM user must have permission to read the target secret from AWS Secrets Manager:

```json
{
 "Version": "2012-10-17",
 "Statement": [
 {
 "Effect": "Allow",
 "Action": [
 "secretsmanager:GetSecretValue",
 "secretsmanager:DescribeSecret"
 ],
 "Resource": "arn:aws:secretsmanager:<region>:<account-id>:secret:<secret-name>*"
 }
 ]
}
```

:::note
Include the trailing `*` in the secret ARN. AWS appends a random suffix to secret names in the ARN, so omitting it can cause access failures.
:::

</TabItem>
<TabItem value="azure-key-vault" label="Azure Key Vault">

 1. Locate the `secretstore` attribute in `values.yaml`.
 2. Add Azure Key Vault configuration. For more information, see [Azure Key Vault secret store](https://docs.dapr.io/reference/components-reference/supported-secret-stores/azure-keyvault/)

 ```yaml
 secretstore:
 enabled: true
 spec:
 type: secretstores.azure.keyvault
 version: v1
 metadata:
 - name: vaultName
 value: "<your-keyvault-name>"
 - name: azureTenantId
 value: "<your-tenant-id>"
 - name: azureClientId
 value: "<your-client-id>"
 - name: azureClientSecret
 value: "<your-client-secret>"
 - name: azureEnvironment
 value: "AZUREPUBLICCLOUD" # Optional: AZUREPUBLICCLOUD, AZURECHINACLOUD, AZUREUSGOVERNMENTCLOUD, AZUREGERMANCLOUD
 ```
 Azure Key Vault supports multiple authentication methods:
 - **Client Secret**: Use `azureClientSecret` with tenant ID and client ID
 - **Certificate**: Use `azureCertificateFile` instead of client secret
 - **Managed Identity**: Omit authentication fields and use Azure managed identity

 For detailed authentication setup, see the [Authenticating to Azure](https://docs.dapr.io/developing-applications/integrations/azure/azure-authentication/authenticating-azure/) documentation.

</TabItem>
<TabItem value="gcp-secret-manager" label="GCP Secret Manager">

1. Locate the `secretstore` attribute in `values.yaml`.
2. Add Google Cloud Secret Manager configuration. For more information, see [GCP Secret Manager](https://docs.dapr.io/reference/components-reference/supported-secret-stores/gcp-secret-manager/)

 The GCP service account used in this configuration must have the `Secret Manager Secret Accessor` role (`roles/secretmanager.secretAccessor`) on the project where your secrets are stored. The metadata values below come from the service account's JSON key file.

 ```yaml
 secretstore:
 enabled: true
 spec:
 type: secretstores.gcp.secretmanager
 version: v1
 metadata:
 - name: type
 value: "service_account"
 - name: project_id
 value: "<project-id>"
 - name: private_key_id
 value: "<private-key-id>"
 - name: private_key
 value: "<private-key>"
 - name: client_email
 value: "<client-email>"
 - name: client_id
 value: "<client-id>"
 - name: auth_uri
 value: "https://accounts.google.com/o/oauth2/auth"
 - name: token_uri
 value: "https://oauth2.googleapis.com/token"
 - name: auth_provider_x509_cert_url
 value: "https://www.googleapis.com/oauth2/v1/certs"
 - name: client_x509_cert_url
 value: "https://www.googleapis.com/robot/v1/metadata/x509/<client-email>"
 ```

</TabItem>
<TabItem value="hashicorp-vault" label="HashiCorp Vault">

1. Locate the `secretstore` attribute in `values.yaml`.
2. Add HashiCorp Vault configuration. For more information, see [HashiCorp Vault](https://docs.dapr.io/reference/components-reference/supported-secret-stores/hashicorp-vault/)

 ```yaml
 secretstore:
 enabled: true
 spec:
 type: secretstores.hashicorp.vault
 version: v1
 metadata:
 - name: vaultAddr
 value: "[vault_address]" # Optional. Default: "https://127.0.0.1:8200"
 - name: caCert # Optional. This or caPath or caPem
 value: "[ca_cert]"
 - name: caPath # Optional. This or CaCert or caPem
 value: "[path_to_ca_cert_file]"
 - name: caPem # Optional. This or CaCert or CaPath
 value: "[encoded_ca_cert_pem]"
 - name: skipVerify # Optional. Default: false
 value: "[skip_tls_verification]"
 - name: tlsServerName # Optional.
 value: "[tls_config_server_name]"
 - name: vaultTokenMountPath # Required if vaultToken not provided. Path to token file.
 value: "[path_to_file_containing_token]"
 - name: vaultToken # Required if vaultTokenMountPath not provided. Token value.
 value: "[vault_token]"
 - name: vaultKVPrefix # Optional. Default: "dapr"
 value: "[vault_prefix]"
 - name: vaultKVUsePrefix # Optional. default: "true"
 value: "[true/false]"
 - name: enginePath # Optional. default: "secret"
 value: "secret"
 - name: vaultValueType # Optional. default: "map"
 value: "map"
 ```

</TabItem>
<TabItem value="kubernetes-secrets" label="Kubernetes Secrets">

1. Locate the `secretstore` attribute in `values.yaml`.
2. Add Kubernetes native secret storage. For more information, see [Kubernetes secrets](https://docs.dapr.io/reference/components-reference/supported-secret-stores/kubernetes-secret-store/)

 ```yaml
 secretstore:
 enabled: true
 spec:
 type: secretstores.kubernetes
 version: v1
 metadata:
 - name: defaultNamespace
 value: "default" # Optional: Default namespace to retrieve secrets from
 - name: kubeconfigPath
 value: "/path/to/kubeconfig" # Optional: Path to kubeconfig file
 ```
 When Dapr is deployed to a Kubernetes cluster, a secret store with the name `kubernetes` is automatically provisioned. You can use this native Kubernetes secret store with no need to create, deploy or maintain a component configuration file.

</TabItem>
<TabItem value="environment-variable-based" label="Environment Variables">

1. Locate the `secretstore` attribute in `values.yaml`.
2. Add Local environment variables as the spec. For more information, see [Local Environment Variables](https://docs.dapr.io/reference/components-reference/supported-secret-stores/envvar-secret-store/)

 ```yaml
 secretstore:
 enabled: true
 spec:
 type: secretstores.local.env
 version: v1
 ```

</TabItem>
</Tabs>

### Image source

Choose how the cluster pulls the app image. Most installs use Atlan's Docker Hub directly; mirror to a private registry if your organization requires it.

<Tabs>
<TabItem value="docker-hub" label="Public Docker Hub" default>

The chart pulls the app image from Atlan's Docker Hub at runtime. The pod needs a Kubernetes secret containing your Docker Hub PAT to authenticate:

```bash
kubectl create secret docker-registry atlan-docker-secret \
 --docker-server=docker.io \
 --docker-username=YOUR_USERNAME \
 --docker-password=YOUR_PAT_TOKEN \
 -n <namespace>
```

- Replace `YOUR_USERNAME` with the Docker Hub username provided by Atlan.
- Replace `YOUR_PAT_TOKEN` with the Personal Access Token (PAT) provided by Atlan.
- Replace `<namespace>` with the namespace you need to install the chart into. The secret and the release must live in the same namespace, or the pod fails with `ImagePullBackOff`.

The downloaded `values.yaml` already references this secret under `imagePullSecrets`. If you use a different secret name, update that field in the file.

</TabItem>
<TabItem value="private-registry" label="Private image repo">

Mirror the Atlan image to your enterprise registry and update `values.yaml` to point at it.

1. Authenticate with Docker Hub using the PAT from Atlan, then pull the source image. The image and tag come from `image.repository` and `image.tag` in the downloaded `values.yaml`:

 ```bash
 docker login -u atlanhq
 # When prompted for password, enter the PAT provided by Atlan
 docker pull <image.repository>:<image.tag>
 ```

2. Push the image to your enterprise's registry. Note down the new repository name and image tag.

3. Update `image.repository` and `image.tag` in `values.yaml` with the new values.

4. If your private registry requires authentication, create an image-pull secret in the target namespace and set `imagePullSecrets` in `values.yaml` to its name.

</TabItem>
</Tabs>

<h2 id="deploy-app">Deploy app</h2>

Follow these steps to deploy the secure app:

* Install the helm chart. The chart directory now carries your edited `values.yaml`, so no `-f` flag is needed:

 ```bash
 helm install {{deploymentValues.helmChartName}}-release ./{{deploymentValues.helmChartName}} -n <namespace>
 ```

 - Replace `<namespace>` with your target Kubernetes namespace.
 - The helm chart name `{{deploymentValues.helmChartName}}` is automatically used from your selected app.

The deployment process typically takes a few minutes to complete depending on factors like Kubernetes cluster resource availability, private image repository download time etc.

<h2 id="verify-app">Verify app</h2>

Follow these steps to verify deployment:

### Verify deployment status on cluster

1. Check pod status:

 ```bash
 kubectl get pods -n <namespace>
 ```

 The output appears similar to:

 ```
 NAME READY STATUS RESTARTS AGE
 <helm-chart-name>-release-<helm-chart-name>-5dff95cd85-cvk5z 1/1 Running 0 2m
 ```
 
 Replace `<helm-chart-name>` with your app's helm chart name (shown in the prerequisites section earlier in this guide).

 The pod status shows `Running` with `1/1` ready containers.

2. Verify logs for the running pod
 
 ```bash
 kubectl logs -n <namespace> -l app.kubernetes.io/name={{deploymentValues.helmChartName}} --tail=50 -f
 ```
 **Example application logs**: Look for these key log messages that confirm successful deployment:

 * `Uvicorn running on http://0.0.0.0:8000` - Web server started
 * `Workflow engine initialized` - Workflow processing ready
 * `dapr initialized. Status: Running` - Dapr runtime active
 * `Starting worker with task queue: atlan-<package-name>-DEPLOYMENT_NAME` - Worker process started (replace `<package-name>` with your app's package name)
 * `GET /server/ready 200` - Health check endpoint responding

### Verify registration via Atlan UI

Once the App is successfully deployed, it communicates to the Atlan tenant and registers itself. Verify App registration is successful in Atlan:

1. In the same Atlan tenant, navigate to **Workflows** > **Agent**.
2. Look for an entry named `<app_name>-<deployment_name>`, where `<app_name>` matches your selected app (for example, "Oracle" or "Microsoft SQL Server") and `<deployment_name>` is the deployment name you entered when generating the config.
3. Confirm the agent status displays as **Active**.

Agent registration and status takes a couple of minutes to reflect in the Atlan UI.

<h2 id="next-steps">Next steps</h2>

* [Configure workflow execution](https://docs.atlan.com/product/connections/self-deployed-runtime/how-tos/configure-workflow-execution): Set up workflow execution with secret retrieval for your Self-deployed Runtime

---

## Install on Kubernetes - BigID

URL: https://docs.atlan.com/product/connections/self-deployed-runtime/how-tos/install-on-kubernetes
**Connector:** BigID (privacy)

> Install an App on Kubernetes using Helm charts, Docker images, and specific configuration

:::info **Did you know?** 
SDR requires additional enablement and licensing. Contact your Atlan representative for details.
:::

:::warning Use the guided install wizard instead
**New Self-Deployed Runtime setups are encouraged to use the [guided install wizard](https://docs.atlan.com/product/connections/self-deployed-runtime/how-tos/install-guided).** It assembles a complete guide tailored to your lifecycle mode, platform, and image procurement on a single page—and it's where new setup options (for example, HTTP proxy and custom CA trust) are documented going forward.

This page is kept for existing users who already reference it and may not include the latest steps.
:::

<h2 id="prerequisites">Prerequisites</h2>

Before you begin, make sure you have:

* `kubectl` installed and configured with administrative access to your target Kubernetes cluster
* Helm version 3.0 or later installed on your deployment machine
* A [Docker Hub Personal Access Token (PAT)](https://start.1password.com/open/i?a=WAVUZSKJO5GMNMVBYWAWECXIUE&v=ouvp3xf5334cxoamyiipzjlewy&i=p76avgzmkkcbftldcuvr5jcof4&h=atlanhq.1password.com) from Atlan
* App-specific helm chart name: `{{deploymentValues.helmChartName}}` 
* Object storage: AWS S3, Google Cloud Storage, or Azure Blob Storage with read/write permissions
* Secret store access: AWS Secret Manager, Azure Key Vault, GCP Secret Manager, HashiCorp Vault, or Kubernetes Secrets with read permissions

:::warning For security reasons, the Docker Hub PAT Token is regenerated on a periodic basis. 
In case the token is embedded in automation scripts or CI/CD pipelines, those jobs may fail. 
Contact your Atlan representative for the latest token.
:::

<h2 id="download-required-files">Download required files</h2>

<h3 id="download-helm-chart">Download Helm chart</h3>

Download the Helm chart for the app:

```bash
helm pull oci://registry-1.docker.io/atlanhq/{{deploymentValues.helmChartName}} --untar
```

This unpacks the chart's `Chart.yaml`, `templates/`, and a default `values.yaml` into `./{{deploymentValues.helmChartName}}/`. You'll replace this default `values.yaml` with your Marketplace copy in the next step.

<h3 id="download-values-yaml">Download values.yaml</h3>

Atlan generates the helm `values.yaml` for your runtime directly from the Marketplace UI, including the OAuth client credentials your runtime uses to authenticate to your tenant.

1. Sign in to your Atlan tenant as an administrator, open **Connector** > **Marketplace**, select the app you want to deploy, and click **Download config for Self-Deployed Runtime** in the right-hand sidebar.

2. In the dialog, keep **New deployment** selected (this mints the OAuth client and full config for a fresh runtime), choose **Kubernetes (Helm)** as the deployment target, and enter a **Deployment name**: a short identifier (lowercase letters, digits, and dashes) that identifies this runtime; the agent in **Workflows > Agent** is named `<app_name>-<deployment_name>`.

3. Click **Generate**. Atlan mints a dedicated OAuth client and produces a `values.yaml` file with:
 - `global.atlanBaseUrl`, `global.clientId`, and `global.clientSecret` already filled in.
 - `image.repository`, `image.tag`, and `name` pinned to the active version for your tenant.
 - `objectstore` and `secretstore` placeholders for you to configure below.

<h3 id="replace-chart-values">Replace chart values.yaml</h3>

Replace the default `values.yaml` inside the unpacked chart with the `values.yaml` you downloaded from the Marketplace.

From this point on, all edits to `values.yaml` must be made inside `./{{deploymentValues.helmChartName}}/`.

<h2 id="modify-values-yaml">Modify values.yaml</h2>

### Object storage

Self-Deployed Runtime needs a store for reading or writing files. Configure the object storage that matches your environment:

:::tip Don't see your preferred object store?
If your preferred object store isn't listed here, [reach out to Atlan support](https://docs.atlan.com/support/submit-request). Support for additional object stores may be available.
:::

<Tabs>
<TabItem value="aws-s3" label="AWS S3" default>

**Required permissions:**

Apply object-level actions to `arn:aws:s3:::BUCKET/*` and the list action to `arn:aws:s3:::BUCKET` in separate IAM statement entries.

| IAM action | Operations covered |
|---|---|
| `s3:GetObject` | GetObject (full and byte-range), HeadObject |
| `s3:PutObject` | PutObject, CreateMultipartUpload, UploadPart, CompleteMultipartUpload |
| `s3:AbortMultipartUpload` | Abort in-flight multipart upload on error (required for streaming write error paths) |
| `s3:DeleteObject` | DeleteObject and DeleteObjects (bulk batch—same IAM action) |
| `s3:ListBucket` | ListObjectsV2—bucket-level permission, not object-level |

```json
{
 "Version": "2012-10-17",
 "Statement": [
 {
 "Effect": "Allow",
 "Action": [
 "s3:GetObject",
 "s3:PutObject",
 "s3:AbortMultipartUpload",
 "s3:DeleteObject"
 ],
 "Resource": "arn:aws:s3:::YOUR-BUCKET/*"
 },
 {
 "Effect": "Allow",
 "Action": "s3:ListBucket",
 "Resource": "arn:aws:s3:::YOUR-BUCKET"
 }
 ]
}
```

**AssumeRole**: when using `assumeRoleArn`, the caller identity additionally needs `sts:AssumeRole` on the target role ARN. The role itself holds the bucket policy described earlier.

**Configure:**

 1. Locate the `objectstore` attribute in `values.yaml`.
 2. Add AWS S3 configuration. For more information, see [AWS S3 Binding Spec](https://docs.dapr.io/reference/components-reference/supported-bindings/s3/).

 ```yaml
 objectstore:
 enabled: true
 spec:
 type: bindings.aws.s3
 version: v1
 metadata:
 - name: accessKey #optional, leave this empty for iam authentication
 value: ""
 - name: secretKey #optional, leave this empty for iam authentication
 value: ""
 - name: bucket #required, name of the bucket where application can write
 value: "<bucket-name>"
 - name: region #required, region of the bucket where application can write
 value: "<bucket-region>"
 - name: forcePathStyle
 value: "true"
 ```

</TabItem>
<TabItem value="gcp-storage" label="Google Cloud Storage">

**Required permissions:**

| IAM permission | Operations covered |
|---|---|
| `storage.objects.get` | GetObject (full and byte-range), object metadata / HeadObject equivalent |
| `storage.objects.create` | PutObject, resumable / streaming write |
| `storage.objects.delete` | DeleteObject (GCS has no native bulk-delete API—`delete_prefix` issues parallel single-object deletes) |
| `storage.objects.list` | ListObjects |

No `storage.buckets.*` permissions are needed. The smallest predefined role that covers all four is **`roles/storage.objectAdmin`** scoped to the bucket. Alternatively, create a custom role with exactly these four permissions.

**Configure:**

 1. Locate the `objectstore` attribute in `values.yaml`.
 2. Add Google Cloud Storage configuration. For more information, see [GCP Storage Bucket binding spec](https://docs.dapr.io/reference/components-reference/supported-bindings/gcpbucket/)

 ```yaml
 objectstore:
 enabled: true
 spec:
 type: bindings.gcp.bucket
 version: v1
 metadata:
 - name: bucket
 value: "your-gcs-bucket-name"
 - name: type
 value: "service_account"
 - name: project_id
 value: "your-gcp-project-id"
 ```

</TabItem>
<TabItem value="azure-blob" label="Azure Blob Storage">

**Required permissions:**

**RBAC**—assign at container or storage-account scope:

| RBAC action | Operations covered |
|---|---|
| `Microsoft.Storage/storageAccounts/blobServices/containers/blobs/read` | GetBlob, GetBlobProperties (HEAD), ListBlobs, byte-range GET |
| `Microsoft.Storage/storageAccounts/blobServices/containers/blobs/write` | PutBlob, PutBlock + PutBlockList (streaming / block write) |
| `Microsoft.Storage/storageAccounts/blobServices/containers/blobs/delete` | DeleteBlob, BlobBatch delete (bulk—up to 256 keys per request) |

The smallest predefined role covering all three is **`Storage Blob Data Contributor`**. `Storage Blob Data Owner` is a superset and is only needed if you additionally require POSIX ACL management on ADLS Gen2.

**SAS token**—minimum permissions at container scope: `r` (read) + `w` (write) + `d` (delete) + `l` (list), that is a container-scoped SAS with **`rwdl`**.

**ADLS Gen2 with POSIX ACLs**: if the storage account has hierarchical namespace enabled and you use ACL-based access control instead of RBAC, the principal needs Execute (`X`) on every parent directory and Read / Write / Delete on the objects in scope. RBAC (`Storage Blob Data Contributor`) is simpler and is recommended unless you have a specific ACL requirement.

**Configure:**

 1. Locate the `objectstore` attribute in `values.yaml`.
 2. Add Azure Blob Storage configuration. For more information, see [Azure Blob Storage binding spec](https://docs.dapr.io/reference/components-reference/supported-bindings/blobstorage/)

 ```yaml
 objectstore:
 enabled: true
 spec:
 type: bindings.azure.blobstorage
 version: v1
 metadata:
 - name: accountName
 value: "your-storage-account-name"
 - name: accountKey
 value: "your-storage-account-key"
 - name: containerName
 value: "your-container-name"
 ```

</TabItem>
</Tabs>

### Secret storage

Self-Deployed Runtime fetches secrets from a secret store to connect to the source systems. The secret store references are used to configure the workflow. Configure the secret store that aligns with your security infrastructure:

:::info Did you know?
Dapr supports additional secret stores which aren't mentioned here. For more information, see [Dapr secret store documentation](https://docs.dapr.io/reference/components-reference/supported-secret-stores/) for other configurations.
:::

:::warning Secret content format and naming
When storing credentials, follow the [secret naming and format requirements](https://docs.atlan.com/product/connections/self-deployed-runtime/how-tos/configure-workflow-execution#secret-content-format).
:::

<Tabs>
<TabItem value="aws-secret-manager" label="AWS Secret Manager" default>
 
 1. Locate the `secretstore` attribute in `values.yaml`.
 2. Add AWS Secret Manager configuration. For more information, see [AWS Secrets Manager](https://docs.dapr.io/reference/components-reference/supported-secret-stores/aws-secret-manager/)

 ```yaml
 secretstore:
 enabled: true
 spec:
 type: secretstores.aws.secretmanager
 version: v1
 metadata:
 - name: region # required, region in which secret is hosted
 value: <secret-region>
 # Needed if IAM authentication is not used
 - name: accessKey
 value: ""
 - name: secretKey
 value: ""
 ```

If you are using IAM role / IRSA authentication, leave `accessKey` and `secretKey` empty.

If you are using an IAM user instead, set:
- `accessKey` to the IAM user's access key ID
- `secretKey` to the IAM user's secret access key

That IAM user must have permission to read the target secret from AWS Secrets Manager:

```json
{
 "Version": "2012-10-17",
 "Statement": [
 {
 "Effect": "Allow",
 "Action": [
 "secretsmanager:GetSecretValue",
 "secretsmanager:DescribeSecret"
 ],
 "Resource": "arn:aws:secretsmanager:<region>:<account-id>:secret:<secret-name>*"
 }
 ]
}
```

:::note
Include the trailing `*` in the secret ARN. AWS appends a random suffix to secret names in the ARN, so omitting it can cause access failures.
:::

</TabItem>
<TabItem value="azure-key-vault" label="Azure Key Vault">

 1. Locate the `secretstore` attribute in `values.yaml`.
 2. Add Azure Key Vault configuration. For more information, see [Azure Key Vault secret store](https://docs.dapr.io/reference/components-reference/supported-secret-stores/azure-keyvault/)

 ```yaml
 secretstore:
 enabled: true
 spec:
 type: secretstores.azure.keyvault
 version: v1
 metadata:
 - name: vaultName
 value: "<your-keyvault-name>"
 - name: azureTenantId
 value: "<your-tenant-id>"
 - name: azureClientId
 value: "<your-client-id>"
 - name: azureClientSecret
 value: "<your-client-secret>"
 - name: azureEnvironment
 value: "AZUREPUBLICCLOUD" # Optional: AZUREPUBLICCLOUD, AZURECHINACLOUD, AZUREUSGOVERNMENTCLOUD, AZUREGERMANCLOUD
 ```
 Azure Key Vault supports multiple authentication methods:
 - **Client Secret**: Use `azureClientSecret` with tenant ID and client ID
 - **Certificate**: Use `azureCertificateFile` instead of client secret
 - **Managed Identity**: Omit authentication fields and use Azure managed identity

 For detailed authentication setup, see the [Authenticating to Azure](https://docs.dapr.io/developing-applications/integrations/azure/azure-authentication/authenticating-azure/) documentation.

</TabItem>
<TabItem value="gcp-secret-manager" label="GCP Secret Manager">

1. Locate the `secretstore` attribute in `values.yaml`.
2. Add Google Cloud Secret Manager configuration. For more information, see [GCP Secret Manager](https://docs.dapr.io/reference/components-reference/supported-secret-stores/gcp-secret-manager/)

 The GCP service account used in this configuration must have the `Secret Manager Secret Accessor` role (`roles/secretmanager.secretAccessor`) on the project where your secrets are stored. The metadata values below come from the service account's JSON key file.

 ```yaml
 secretstore:
 enabled: true
 spec:
 type: secretstores.gcp.secretmanager
 version: v1
 metadata:
 - name: type
 value: "service_account"
 - name: project_id
 value: "<project-id>"
 - name: private_key_id
 value: "<private-key-id>"
 - name: private_key
 value: "<private-key>"
 - name: client_email
 value: "<client-email>"
 - name: client_id
 value: "<client-id>"
 - name: auth_uri
 value: "https://accounts.google.com/o/oauth2/auth"
 - name: token_uri
 value: "https://oauth2.googleapis.com/token"
 - name: auth_provider_x509_cert_url
 value: "https://www.googleapis.com/oauth2/v1/certs"
 - name: client_x509_cert_url
 value: "https://www.googleapis.com/robot/v1/metadata/x509/<client-email>"
 ```

</TabItem>
<TabItem value="hashicorp-vault" label="HashiCorp Vault">

1. Locate the `secretstore` attribute in `values.yaml`.
2. Add HashiCorp Vault configuration. For more information, see [HashiCorp Vault](https://docs.dapr.io/reference/components-reference/supported-secret-stores/hashicorp-vault/)

 ```yaml
 secretstore:
 enabled: true
 spec:
 type: secretstores.hashicorp.vault
 version: v1
 metadata:
 - name: vaultAddr
 value: "[vault_address]" # Optional. Default: "https://127.0.0.1:8200"
 - name: caCert # Optional. This or caPath or caPem
 value: "[ca_cert]"
 - name: caPath # Optional. This or CaCert or caPem
 value: "[path_to_ca_cert_file]"
 - name: caPem # Optional. This or CaCert or CaPath
 value: "[encoded_ca_cert_pem]"
 - name: skipVerify # Optional. Default: false
 value: "[skip_tls_verification]"
 - name: tlsServerName # Optional.
 value: "[tls_config_server_name]"
 - name: vaultTokenMountPath # Required if vaultToken not provided. Path to token file.
 value: "[path_to_file_containing_token]"
 - name: vaultToken # Required if vaultTokenMountPath not provided. Token value.
 value: "[vault_token]"
 - name: vaultKVPrefix # Optional. Default: "dapr"
 value: "[vault_prefix]"
 - name: vaultKVUsePrefix # Optional. default: "true"
 value: "[true/false]"
 - name: enginePath # Optional. default: "secret"
 value: "secret"
 - name: vaultValueType # Optional. default: "map"
 value: "map"
 ```

</TabItem>
<TabItem value="kubernetes-secrets" label="Kubernetes Secrets">

1. Locate the `secretstore` attribute in `values.yaml`.
2. Add Kubernetes native secret storage. For more information, see [Kubernetes secrets](https://docs.dapr.io/reference/components-reference/supported-secret-stores/kubernetes-secret-store/)

 ```yaml
 secretstore:
 enabled: true
 spec:
 type: secretstores.kubernetes
 version: v1
 metadata:
 - name: defaultNamespace
 value: "default" # Optional: Default namespace to retrieve secrets from
 - name: kubeconfigPath
 value: "/path/to/kubeconfig" # Optional: Path to kubeconfig file
 ```
 When Dapr is deployed to a Kubernetes cluster, a secret store with the name `kubernetes` is automatically provisioned. You can use this native Kubernetes secret store with no need to create, deploy or maintain a component configuration file.

</TabItem>
<TabItem value="environment-variable-based" label="Environment Variables">

1. Locate the `secretstore` attribute in `values.yaml`.
2. Add Local environment variables as the spec. For more information, see [Local Environment Variables](https://docs.dapr.io/reference/components-reference/supported-secret-stores/envvar-secret-store/)

 ```yaml
 secretstore:
 enabled: true
 spec:
 type: secretstores.local.env
 version: v1
 ```

</TabItem>
</Tabs>

### Image source

Choose how the cluster pulls the app image. Most installs use Atlan's Docker Hub directly; mirror to a private registry if your organization requires it.

<Tabs>
<TabItem value="docker-hub" label="Public Docker Hub" default>

The chart pulls the app image from Atlan's Docker Hub at runtime. The pod needs a Kubernetes secret containing your Docker Hub PAT to authenticate:

```bash
kubectl create secret docker-registry atlan-docker-secret \
 --docker-server=docker.io \
 --docker-username=YOUR_USERNAME \
 --docker-password=YOUR_PAT_TOKEN \
 -n <namespace>
```

- Replace `YOUR_USERNAME` with the Docker Hub username provided by Atlan.
- Replace `YOUR_PAT_TOKEN` with the Personal Access Token (PAT) provided by Atlan.
- Replace `<namespace>` with the namespace you need to install the chart into. The secret and the release must live in the same namespace, or the pod fails with `ImagePullBackOff`.

The downloaded `values.yaml` already references this secret under `imagePullSecrets`. If you use a different secret name, update that field in the file.

</TabItem>
<TabItem value="private-registry" label="Private image repo">

Mirror the Atlan image to your enterprise registry and update `values.yaml` to point at it.

1. Authenticate with Docker Hub using the PAT from Atlan, then pull the source image. The image and tag come from `image.repository` and `image.tag` in the downloaded `values.yaml`:

 ```bash
 docker login -u atlanhq
 # When prompted for password, enter the PAT provided by Atlan
 docker pull <image.repository>:<image.tag>
 ```

2. Push the image to your enterprise's registry. Note down the new repository name and image tag.

3. Update `image.repository` and `image.tag` in `values.yaml` with the new values.

4. If your private registry requires authentication, create an image-pull secret in the target namespace and set `imagePullSecrets` in `values.yaml` to its name.

</TabItem>
</Tabs>

<h2 id="deploy-app">Deploy app</h2>

Follow these steps to deploy the secure app:

* Install the helm chart. The chart directory now carries your edited `values.yaml`, so no `-f` flag is needed:

 ```bash
 helm install {{deploymentValues.helmChartName}}-release ./{{deploymentValues.helmChartName}} -n <namespace>
 ```

 - Replace `<namespace>` with your target Kubernetes namespace.
 - The helm chart name `{{deploymentValues.helmChartName}}` is automatically used from your selected app.

The deployment process typically takes a few minutes to complete depending on factors like Kubernetes cluster resource availability, private image repository download time etc.

<h2 id="verify-app">Verify app</h2>

Follow these steps to verify deployment:

### Verify deployment status on cluster

1. Check pod status:

 ```bash
 kubectl get pods -n <namespace>
 ```

 The output appears similar to:

 ```
 NAME READY STATUS RESTARTS AGE
 <helm-chart-name>-release-<helm-chart-name>-5dff95cd85-cvk5z 1/1 Running 0 2m
 ```
 
 Replace `<helm-chart-name>` with your app's helm chart name (shown in the prerequisites section earlier in this guide).

 The pod status shows `Running` with `1/1` ready containers.

2. Verify logs for the running pod
 
 ```bash
 kubectl logs -n <namespace> -l app.kubernetes.io/name={{deploymentValues.helmChartName}} --tail=50 -f
 ```
 **Example application logs**: Look for these key log messages that confirm successful deployment:

 * `Uvicorn running on http://0.0.0.0:8000` - Web server started
 * `Workflow engine initialized` - Workflow processing ready
 * `dapr initialized. Status: Running` - Dapr runtime active
 * `Starting worker with task queue: atlan-<package-name>-DEPLOYMENT_NAME` - Worker process started (replace `<package-name>` with your app's package name)
 * `GET /server/ready 200` - Health check endpoint responding

### Verify registration via Atlan UI

Once the App is successfully deployed, it communicates to the Atlan tenant and registers itself. Verify App registration is successful in Atlan:

1. In the same Atlan tenant, navigate to **Workflows** > **Agent**.
2. Look for an entry named `<app_name>-<deployment_name>`, where `<app_name>` matches your selected app (for example, "Oracle" or "Microsoft SQL Server") and `<deployment_name>` is the deployment name you entered when generating the config.
3. Confirm the agent status displays as **Active**.

Agent registration and status takes a couple of minutes to reflect in the Atlan UI.

<h2 id="next-steps">Next steps</h2>

* [Configure workflow execution](https://docs.atlan.com/product/connections/self-deployed-runtime/how-tos/configure-workflow-execution): Set up workflow execution with secret retrieval for your Self-deployed Runtime

---
