> For the complete documentation index, see [llms.txt](https://docs.devolutions.net/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.devolutions.net/pam/knowledge-base/knowledge-base-articles/external-secrets-operator.md).

# External Secrets Operator

External Secrets Operator integrates with [Devolutions Server](file:///) for secret management.

{% hint style="info" %}
The values in this guide (e.g., `your-application-id`) are placeholders, replace them with the specific values of your environment.
{% endhint %}

### Authentication

Devolutions Server authentication uses ***Application ID*** and ***Application secret*** credentials.

#### Creating an application identity in Devolutions Server

1. Log into your Devolutions Server's web interface.
2. Navigate to ***Administration*** – ***Applications identities***.
3. Click ***Add*** (**+**) to create a new application.
4. Configure the application with the permissions required to access the desired vaults and entries.
5. Save the ***Application ID*** and ***Application secret***.

#### Creating the Kubernetes secret

Create a Kubernetes secret containing your Devolutions Server credentials using the following script:

```bash
kubectl create secret generic dvls-credentials \
  --from-literal=app-id="your-application-id" \
  --from-literal=app-secret="your-application-secret"
```

#### Creating a SecretStore

```bash
apiVersion: external-secrets.io/v1
kind: SecretStore
metadata:
  name: dvls-store
  namespace: default
spec:
  provider:
    dvls:
      serverUrl: 'https://devolutions-server.example.com'
      vault: 'my-vault'
      auth:
        secretRef:
          appId:
            name: dvls-credentials
            key: app-id
          appSecret:
            name: dvls-credentials
            key: app-secret
```

| **Field**                  | **Description**                                                                                                                                                                                 |
| -------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `serverUrl`                | The URL of the Devolutions Server instance (e.g., `https://devolutions-server.example.com`)                                                                                                     |
| `vault`                    | The name or UUID of the vault from which to fetch secrets. When omitted, the vault must be specified in the secret key using the legacy `<vault-id>/<entry-id>` format. This field is optional. |
| `insecure`                 | Set to `true` to allow plain HTTP connections. **Not recommended for production**. This field is optional.                                                                                      |
| `auth.secretRef.appId`     | Reference to the secret containing the ***Application ID***.                                                                                                                                    |
| `auth.secretRef.appSecret` | Reference to the secret containing the ***Application secret***.                                                                                                                                |

{% hint style="info" %}
For `ClusterSecretStore`, ensure you specify the `namespace` in the secret references.
{% endhint %}

### Referencing secrets

Entries can be referenced by UUID or name:

| **Format**                       | **Example**                               |
| -------------------------------- | ----------------------------------------- |
| **Entry UUID**                   | `7c9e6679-7425-40de-944b-e07fc1f90ae7`    |
| **Entry name**                   | `db-credentials`                          |
| **Entry name with folder path**  | `infrastructure/databases/db-credentials` |
| **Folder path with backslashes** | `infrastructure\databases\db-credentials` |

The vault is configured in the SecretStore's `vault` field (name or UUID), so the key only needs to identify the entry.

#### Folder paths

If an entry is inside a folder, you can include the folder path before the entry name. Both forward slashes (`/`) and backslashes (`\`) are accepted as path separators:

```bash
folder/subfolder/entry-name
folder\subfolder\entry-name
```

{% hint style="warning" %}
When using backslashes in YAML, you must escape them with a double backslash (`\\`):
{% endhint %}

```
key: "folder\\subfolder\\entry-name"
```

Forward slashes do not need escaping and are recommended for simplicity.

{% hint style="warning" %}
Entry names containing forward slashes (`/`) or backslashes (`</code>) are not supported with name-based lookups, as those characters are interpreted as path separators. Use the entry UUID instead.`
{% endhint %}

The folder path is optional. Without a path, the provider searches across all folders in the vault. If multiple entries share the same name in different folders, you can either specify the folder path or use the entry UUID to disambiguate.

Name-based lookups resolve the name to a UUID at runtime via an API call. If multiple credential entries match, an error is returned. For write-heavy scenarios (frequent `PushSecret` operations), prefer UUID references to avoid the extra lookup per operation.

You can find UUIDs in the Devolutions Server web interface by viewing the entry properties.

### Supported credential types

Devolutions Server supports multiple credential types. The provider maps each type to specific properties:

| **Credential type**         | Devolutions Server **entry type** | **Available properties**                                          |
| --------------------------- | --------------------------------- | ----------------------------------------------------------------- |
| **Default**                 | Credential                        | `username`, `password`, `domain`                                  |
| **Access Code**             | Secret                            | `password`                                                        |
| **API Key**                 | Credential                        | `api-id`, `api-key`, `tenant-id`                                  |
| **Azure Service Principal** | Credential                        | `client-id`, `client-secret`, `tenant-id`                         |
| **Connection String**       | Credential                        | `connection-string`                                               |
| **Private Key**             | Credential                        | `username`, `password`, `private-key`, `public-key`, `passphrase` |

All entries also include `entry-id` and `entry-name` metadata properties.

{% hint style="warning" %}
When no `property` is specified, the `password` field is returned by default.

In the Devolutions Server web interface, "Secret" entries appear as a distinct entry type and are mapped to the Access Code credential subtype internally.
{% endhint %}

### Examples

#### Fetching individual properties

To fetch specific properties from a credential entry:

```bash
---
# Fetch a single property from a credential entry by name
apiVersion: external-secrets.io/v1
kind: ExternalSecret
metadata:
  name: database-credentials
spec:
  refreshInterval: 1h
  secretStoreRef:
    kind: SecretStore
    name: dvls-store
  target:
    name: database-secret
    creationPolicy: Owner
  data:
    - secretKey: username
      remoteRef:
        key: 'db-credentials'
        property: username
    - secretKey: password
      remoteRef:
        key: 'db-credentials'
        property: password
---
# Fetch all fields from a credential entry with folder path
apiVersion: external-secrets.io/v1
kind: ExternalSecret
metadata:
  name: api-credentials
spec:
  refreshInterval: 1h
  secretStoreRef:
    kind: SecretStore
    name: dvls-store
  target:
    name: api-secret
    creationPolicy: Owner
  dataFrom:
    - extract:
        key: 'infrastructure/apis/my-api-key'
---
# Fetch a Secret entry (Access Code type) by UUID
apiVersion: external-secrets.io/v1
kind: ExternalSecret
metadata:
  name: app-secret
spec:
  refreshInterval: 1h
  secretStoreRef:
    kind: SecretStore
    name: dvls-store
  target:
    name: app-secret
    creationPolicy: Owner
  data:
    - secretKey: secret
      remoteRef:
        key: '<entry-uuid>'
        property: password
```

#### Using dataFrom to extract all fields

When using `dataFrom.extract`, all available properties from the credential entry will be synced to the Kubernetes secret.

### Push secrets

The Devolutions Server provider supports pushing secrets back to Devolutions Server:

```bash
apiVersion: external-secrets.io/v1alpha1
kind: PushSecret
metadata:
  name: push-to-dvls
spec:
  refreshInterval: 1h
  secretStoreRefs:
    - name: dvls-store
      kind: SecretStore
  selector:
    secret:
      name: my-k8s-secret
  data:
    - match:
        secretKey: password
        remoteRef:
          # When vault is set in the SecretStore, remoteKey is the entry name
          # (or path/name). Without vault, use the legacy 'vault-uuid/entry-uuid' format.
          remoteKey: 'db-credentials'
```

**Note:** Push secret updates an existing entry's password field. The entry must already exist in Devolutions Server.

### Limitations

* **GetAllSecrets**: The `find` operation for discovering secrets is not currently supported.
* **Custom CA Certificates**: Custom TLS certificates for self-signed Devolutions Server instances are not yet supported. Use the `SSL_CERT_FILE` environment variable as a workaround.
* **Certificate entries**: Certificate entry types (`Document/Certificate`) are not currently supported. Only Credential entries are supported.

### Troubleshooting

#### Authentication errors

If you receive authentication errors:

1. Verify the Application ID and Secret are correct.
2. Ensure the application has the necessary permissions in Devolutions Server.
3. Check that the Devolutions Server server URL is accessible from your Kubernetes cluster.

#### Entry not found

If an entry cannot be found:

1. Verify the vault and entry references are correct (UUID or name)
2. Ensure the application has at least read access to the vault
3. Check that the entry exists and is a Credential or Secret type entry
4. Ensure the application has at least read, view password, and connect (execute) permissions on the entry

#### Multiple entries found

If you receive a "multiple entries found" error when using name-based references, it means more than one credential entry shares the same name in the vault. Use the entry UUID instead of the name to target the correct entry.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.devolutions.net/pam/knowledge-base/knowledge-base-articles/external-secrets-operator.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
