# Apono Vault

Many organizations enforce strict policies that prohibit storing highly privileged credentials in third-party SaaS platforms. Security teams still need a way to securely store credentials such as cloud root accounts, database sysadmins, and emergency breakglass credentials while ensuring access is tightly controlled.

Apono Vault solves this problem by allowing you to deploy a lightweight vault inside your own Kubernetes environment. This vault stores secrets locally while Apono manages just-in-time (JIT) access, approvals, and auditing.

Through this integration, your organization can:

* Store sensitive credentials entirely inside your own infrastructure
* Eliminate hard-coded secrets and credentials sprawl
* Grant engineers temporary, policy-controlled access to secrets
* Maintain Zero Standing Privileges (ZSP) through time-bound access
* Audit who accessed privileged credentials and when

{% hint style="info" %}
Apono Vault is built on [OpenBao](https://openbao.org/) and deployed directly in your Kubernetes cluster.
{% endhint %}

***

### Prerequisites

<table><thead><tr><th width="200.16015625">Item</th><th>Description</th></tr></thead><tbody><tr><td><strong>Apono Connector</strong></td><td>On-prem connection serving as a bridge between Kubernetes and Apono<br><br>Learn how to <a href="../kubernetes-environment/apono-connector-for-kubernetes">install</a> or <a href="../kubernetes-environment/apono-connector-for-kubernetes/updating-a-kubernetes-connector">update a connector for Kubernetes</a>.<br><br><strong>NOTE</strong>: The connector must have permissions to access the Kubernetes namespace where the vault is deployed and read the vault credentials secret.</td></tr><tr><td><strong>Apono CLI</strong></td><td>Command-line tool enabling you to view, request, and receive permission to resources that are centrally managed by Apono<br><br>Version <strong>1.3.5 or later</strong> is required for vault operations.<br><br>Learn how to <a href="../access-requests-and-approvals/cli/install-and-manage-the-apono-cli">install and manage the Apono CLI</a>.</td></tr><tr><td><strong>Kubernetes Cluster</strong></td><td>Kubernetes 1.30 or later with a configured <code>PersistentVolume</code> provisioner<br><br>Learn how to <a href="https://kubernetes.io/docs/tutorials/kubernetes-basics/create-cluster/">create a cluster</a>.</td></tr><tr><td><strong>Helm</strong></td><td>Helm 3.12 or later installed in your environment<br><br>Learn how to <a href="https://helm.sh/docs/intro/install/">install Helm</a>.</td></tr><tr><td><strong>kubectl</strong></td><td><p><code>kubectl</code> configured to access your Kubernetes cluster</p><p><br>Learn how to <a href="https://kubernetes.io/docs/concepts/configuration/organize-cluster-access-kubeconfig/">organize cluster access</a> with the <code>kubectl</code> command-line tool.</p></td></tr></tbody></table>

***

### Deploy Apono Vault

Deploy Apono Vault in your Kubernetes cluster using one of the following methods.

{% tabs %}
{% tab title="Install script" %}
{% hint style="info" %}
**We recommend this deployment option**.
{% endhint %}

Follow this step to deploy Apono Vault in your cluster:

1. Run the installation script to automatically add the Helm repository, deploy the vault, and output the configuration details required for the Apono integration.

```
curl -s https://apono-public.s3.amazonaws.com/local-apono-vault/install.sh | bash
```

{% hint style="success" %}
**Optional parameters**

You can append parameters to the install script to add specific conditions to the vault deployment.

**Deploy to a custom namespace**:

```
curl -s https://apono-public.s3.amazonaws.com/local-apono-vault/install.sh | bash -s -- -n my-namespace
```

\
**Deploy to a specific Kubernetes context**:

```
curl -s https://apono-public.s3.amazonaws.com/local-apono-vault/install.sh | bash -s -- --kube-context my-cluster
```

\
**Deploy with custom Helm parameters**:

```
curl -s https://apono-public.s3.amazonaws.com/local-apono-vault/install.sh | bash -s -- \
  --kube-context my-cluster -n my-namespace \
  --set vault.server.dataStorage.size=5Gi
```

\
**Use a custom values file**:

```
curl -s https://apono-public.s3.amazonaws.com/local-apono-vault/install.sh | bash -s -- -f custom-values.yaml
```

{% endhint %}
{% endtab %}

{% tab title="Manual Helm deployment" %}
Follow this step to deploy Apono Vault in your cluster:

1. Deploy the vault using Helm.

```
helm repo add apono https://apono-io.github.io/apono-helm-charts
helm repo update
kubectl create namespace apono-vault
helm install apono-vault apono/apono-vault -n apono-vault --wait
```

{% hint style="info" %}
The `--wait` flag blocks the vault until all resources, including the initialization job, are ready. To monitor initialization in real time, omit `--wait` and tail the logs:

```
kubectl logs -f job/apono-vault-init -n apono-vault
```

{% endhint %}

{% hint style="success" %}
**Optional parameters**

You can add parameters in Helm to add specific conditions to the vault deployment.

**Deploy to a custom namespace**:

```
kubectl create namespace my-namespace
helm install apono-vault apono/apono-vault -n my-namespace --wait
```

{% endhint %}
{% endtab %}
{% endtabs %}

<details>

<summary><strong>Configurable parameters</strong></summary>

You can customize your deployment by passing the following Helm values with the `--set` flag.

<table><thead><tr><th width="287.98828125">Parameter</th><th width="285.3046875">Description</th><th>Default</th></tr></thead><tbody><tr><td><strong>vault.server.image.tag</strong></td><td>Vault image version</td><td><code>2.5.1</code></td></tr><tr><td><strong>vault.server.resources.requests.memory</strong></td><td>Memory request</td><td><code>128Mi</code></td></tr><tr><td><strong>vault.server.resources.requests.cpu</strong></td><td>CPU request</td><td><code>100m</code></td></tr><tr><td><strong>vault.server.resources.limits.memory</strong></td><td>Memory limit</td><td><code>256Mi</code></td></tr><tr><td><strong>vault.server.resources.limits.cpu</strong></td><td>CPU limit</td><td><code>250m</code></td></tr><tr><td><strong>vault.server.dataStorage.size</strong></td><td>PVC size for Raft data</td><td><code>1Gi</code></td></tr><tr><td><strong>vault.server.dataStorage.storageClass</strong></td><td>Storage class (uses cluster default if unset)</td><td><code>null</code></td></tr><tr><td><strong>vault.server.service.type</strong></td><td>Kubernetes service type</td><td><code>ClusterIP</code></td></tr><tr><td><strong>vault.server.service.port</strong></td><td>Service port</td><td><code>8200</code></td></tr></tbody></table>

**Example**:

```
curl -s https://apono-public.s3.amazonaws.com/local-apono-vault/install.sh | bash -s -- \
  --kube-context my-cluster \
  -n apono-vault \
  --set vault.server.image.tag=2.5.1 \
  --set vault.server.resources.requests.memory=128Mi \
  --set vault.server.resources.requests.cpu=100m \
  --set vault.server.resources.limits.memory=256Mi \
  --set vault.server.resources.limits.cpu=250m \
  --set vault.server.dataStorage.size=5Gi \
  --set vault.server.service.type=ClusterIP \
  --set vault.server.service.port=8200

```

</details>

#### Record installation output

After installation is complete, the output displays the connector configuration values you need to integrate Apono Vault. Record the values below.

| Setting          | Description                                            | Example                                                 |
| ---------------- | ------------------------------------------------------ | ------------------------------------------------------- |
| **Internal URL** | Cluster-internal URL for the vault                     | `http://apono-vault.apono-vault.svc.cluster.local:8200` |
| **External URL** | Optional externally accessible vault endpoint          | —                                                       |
| **Namespace**    | Kubernetes namespace where the vault was deployed      | `apono-vault`                                           |
| **Secret Name**  | Kubernetes secret containing the `AppRole` credentials | `apono-vault-role`                                      |

***

### Integrate Apono Vault

{% hint style="success" %}
You can also use the steps below to integrate with Apono using Terraform.

In step **11**, instead of clicking **Confirm**, follow the **Are you integrating with Apono using Terraform?** guidance.
{% endhint %}

Follow these steps to complete the integration:

1. On the [**Catalog**](https://app.apono.io/catalog/connect-integration/apono-vault) tab, click **Apono Vault**. The **Connect Integration** page appears.
2. Under **Discovery**, select one or both of the Apono Vault resource types (**Secret** and **Management**).

{% hint style="warning" %}
Users granted access to a resource type will be able to perform [different actions](#management-access) depending on their permission level. Granted permissions apply **only** to the secrets requested by the user.
{% endhint %}

3. Click **Next**. The **Apono connector section** expands.
4. From the dropdown menu, select a connector. Choosing a connector links Apono to all the services available on the account where the connector is located.

{% hint style="success" %}
If the desired connector is not listed, click **+ Add new connector** and follow the instructions to [install the connector](https://docs.apono.io/docs/kubernetes-environment/apono-connector-for-kubernetes).
{% endhint %}

5. Click **Next**. The **Integration Config** section expands.
6. Define the **Integration Config** settings.

   <table><thead><tr><th width="185">Setting</th><th>Description</th></tr></thead><tbody><tr><td><strong>Integration Name</strong></td><td>Unique, alphanumeric, user-friendly name used to identify this integration when constructing an access flow</td></tr><tr><td><strong>Vault Internal URL</strong></td><td>Cluster-internal vault endpoint<br><br>Copy this value from the <a href="#record-installation-output">installation output</a>.</td></tr><tr><td><strong>Vault External URL</strong></td><td>Optional external endpoint if the vault service is exposed outside the cluster<br><br>Copy this value from the <a href="#record-installation-output">installation output</a>.</td></tr></tbody></table>
7. Click **Next**. The **Secret Store** section expands.
8. Enter your Kubernetes secret in the **Secret Store**.

<table><thead><tr><th width="199.96875">Field</th><th>Description</th></tr></thead><tbody><tr><td><strong>Namespace</strong></td><td><p>Kubernetes namespace where the vault is deployed</p><p><br>Copy this value from the <a href="#record-installation-output">installation output</a>.</p></td></tr><tr><td><strong>Name</strong></td><td>Kubernetes secret containing the <code>AppRole</code> credentials<br><br>Copy this value from the <a href="#record-installation-output">installation output</a>.</td></tr></tbody></table>

9. Click **Next**. The **Get more with Apono** section expands.
10. Define the **Get more with Apono** settings.

    <table><thead><tr><th width="207">Setting</th><th>Description</th></tr></thead><tbody><tr><td><strong>Custom Access Details</strong></td><td>(Optional) Instructions explaining how to access this integration's resources<br><br>Upon accessing an integration, a message with these instructions will be displayed to end users in the User Portal. The message may include up to <strong>400 characters</strong>.<br><br>To view the message as it appears to end users, click <strong>Preview</strong>.</td></tr><tr><td><strong>Integration Owner</strong></td><td><p>(Optional) Fallback approver if no <a href="../access-flows/dynamic-access-management/resource-and-integration-owners">resource owner</a> is found<br><br>Follow these steps to define one or several integration owners:</p><ol><li>From the <strong>Attribute</strong> dropdown menu, select <strong>User</strong> or <strong>Group</strong> under the relevant identity provider (IdP) platform.</li><li>From the <strong>Value</strong> dropdown menu, select one or multiple users or groups.</li></ol><p><br><strong>NOTE</strong>: When <strong>Resource Owner</strong> is defined, an <strong>Integration Owner</strong> must be defined.</p></td></tr><tr><td><strong>Resource Owner</strong></td><td><p>(Optional) Group or role responsible for managing access approvals or rejections for the resource<br><br>Follow these steps to define one or several <a href="../access-flows/dynamic-access-management/resource-and-integration-owners">resource owners</a>:</p><ol><li>Enter a <strong>Key name</strong>. This value is the name of the tag created in your cloud environment.</li><li>From the <strong>Attribute</strong> dropdown menu, select an attribute under the IdP platform to which the key name is associated.<br><br>Apono will use the value associated with the key (tag) to identify the resource owner. When you update the membership of the group or role in your IdP platform, this change is also reflected in Apono.</li></ol><p><br><strong>NOTE</strong>: When this setting is defined, an <strong>Integration Owner</strong> must also be defined.</p></td></tr></tbody></table>
11. Click **Confirm**.

<details>

<summary>💡Are you integrating with Apono using Terraform?</summary>

If you want to integrate with Apono using Terraform, follow these steps instead of clicking **Confirm**:

1. At the top of the screen, click **View as Code**. A modal appears with the completed Terraform configuration code.
2. Click to copy the code.
3. Make any additional edits.
4. Deploy the code in your Terraform.

Refer to [Integration Config Metadata](https://app.gitbook.com/s/MwlUUTWervcv32GebSwo/integration-metadata/apono-vault) for more details about the schema definition.

</details>

Now that you have completed this integration, you can [create access flows](https://docs.apono.io/docs/access-flows/access-flows) that grant permission to your Apono Vault secrets. Users who are granted access can [manage secrets](#manage-secrets-in-apono-vault) using the Apono CLI.

***

### Manage secrets in Apono Vault

Users can perform different actions in Apono Vault depending on the resource types and permissions they have been granted through an access flow.

{% tabs %}
{% tab title="Management access" %}
Users granted access to the **Management** resource type can manage secrets within the vault. However, their available actions depend on their granted permissions.

| Permission    | List | Create | Fetch | Update | Delete |
| ------------- | ---- | ------ | ----- | ------ | ------ |
| **Admin**     | ✅    | ✅      | ✅     | ✅      | ✅      |
| **ReadWrite** | ✅    | ✅      | ✅     | ✅      | ❌      |
| **ReadOnly**  | ✅    | ❌      | ✅     | ❌      | ❌      |

**List secrets**:

```
apono vault list --vault-id "<vault-id>"
```

**Create a secret**:

```
apono vault create <mount>/<secret-name> \
  --vault-id "<vault-id>" \
  --value '{"key": "value"}'
```

**Fetch a secret**:

```
apono vault fetch <mount>/<secret-name> \
  --vault-id "<vault-id>"
```

**Update a secret**:

```
apono vault update <mount>/<secret-name> \
  --vault-id "<vault-id>" \
  --value '{"key": "new-value"}'
```

**Delete a secret**:

```
apono vault delete <mount>/<secret-name> \
  --vault-id "<vault-id>"
```

{% endtab %}

{% tab title="Secret access" %}
Users granted the **Secret** resource type receive `ReadOnly` permissions and can fetch specific secrets.

```
apono vault fetch <secret-name> --vault-id "<vault-id>"
```

{% endtab %}
{% endtabs %}

***

### Troubleshooting Apono Vault

Expand the sections below to troubleshoot common issues. Contact Apono Support if you require additional help.

<details>

<summary><strong>Initialization job failed</strong></summary>

Run the following command to check the initialization job logs.

```
kubectl logs job/apono-vault-init -n apono-vault
```

</details>

<details>

<summary><strong>Vault does not auto-unseal after restart</strong></summary>

Run the following command to verify the unseal secret contains real values.

```
kubectl get secret apono-vault-unseal -n apono-vault \
  -o jsonpath='{.data.unseal-key}' | base64 -d
```

If the value is `placeholder`, the initialization job has failed. Re-run the initialization.

```
kubectl delete job apono-vault-init -n apono-vault
helm upgrade apono-vault apono/apono-vault -n apono-vault

```

</details>

<details>

<summary><strong>Pod stuck in CrashLoopBackOff</strong></summary>

Run the following command to check the vault pod logs.

```
kubectl logs -n apono-vault apono-vault-0
```

</details>

<details>

<summary><strong>Raft lock file error</strong></summary>

If a vault pod is force-deleted, a stale Raft lock file may remain.

Run the following command to reinstall the vault.

```
helm uninstall apono-vault -n apono-vault
kubectl delete pvc -n apono-vault data-apono-vault-0
```

Then, reinstall the vault using one of the deployment methods above.

{% hint style="danger" %}
Deleting the PVC **permanently removes** all vault data.
{% endhint %}

</details>

***

### Uninstall Apono Vault

{% hint style="danger" %}
Deleting the PVC **permanently removes** all vault data.
{% endhint %}

Follow these steps to uninstall Apono Vault:

1. Run the following command to uninstall the vault deployment.

```
helm uninstall apono-vault -n apono-vault
```

2. (Optional) Run the following command to fully clean the environment.

```
kubectl delete pvc -n apono-vault data-apono-vault-0
kubectl delete secret -n apono-vault apono-vault-unseal apono-vault-role
kubectl delete namespace apono-vault
```
