---
title: Akeyless Plugin
description: Using Akeyless Platform secrets with Varlock
---

import { Steps, Icon } from '@astrojs/starlight/components';
import Badge from '@/components/Badge.astro';

<div class="page-badges">
  <Badge npmPackage="@varlock/akeyless-plugin" />
</div>

Our Akeyless plugin enables secure loading of secrets from [Akeyless Platform](https://www.akeyless.io/) using declarative instructions within your `.env` files.

The plugin uses Akeyless's REST API with API Key or [OIDC](/guides/oidc/) authentication and supports static, dynamic, and rotated secret types.

## Features

- **API Key authentication** - Simple Access ID + Access Key authentication
- **[OIDC authentication](/guides/oidc/)** - Authenticate using platform OIDC tokens (Vercel, GitHub Actions, etc.)
- **Static secrets** - Fetch key/value secrets
- **Dynamic secrets** - Fetch on-demand generated credentials (database, cloud, etc.)
- **Rotated secrets** - Fetch auto-rotated credentials
- **JSON key extraction** from secrets using `#` syntax or named `key` parameter
- **Path prefixing** with `pathPrefix` option for organized secret management
- **Gateway support** - Use a self-hosted [Akeyless Gateway](https://docs.akeyless.io/docs/api-gateway) via custom API URL
- **Auto-infer secret name** from environment variable names
- Support for multiple Akeyless instances
- Automatic token caching and renewal
- Lightweight implementation using REST API (no SDK dependencies)

For global cache mode behavior and CLI cache controls, see the [Caching guide](/guides/caching/).

## Installation and setup

In a JS/TS project, you may install the `@varlock/akeyless-plugin` package as a normal dependency.
Otherwise you can just load it directly from your `.env.schema` file, as long as you add a version specifier.
See the [plugins guide](/guides/plugins/#installation) for more instructions on installing plugins.

```env-spec title=".env.schema"
# 1. Load the plugin
# @plugin(@varlock/akeyless-plugin)
#
# 2. Initialize the plugin - see below for more details on options
# @initAkeyless(accessId=$AKEYLESS_ACCESS_ID, accessKey=$AKEYLESS_ACCESS_KEY)
```

### API Key authentication

The plugin authenticates using an API Key consisting of an Access ID and Access Key:

<Steps>
1. **Create an API Key in Akeyless** (see Akeyless Setup section below)

2. **Wire up the credentials in your config**. Add config items for the Access ID and Access Key, and reference them when initializing the plugin.

    ```env-spec title=".env.schema"
    # @plugin(@varlock/akeyless-plugin)
    # @initAkeyless(accessId=$AKEYLESS_ACCESS_ID, accessKey=$AKEYLESS_ACCESS_KEY)
    # ---

    # @type=akeylessAccessId
    AKEYLESS_ACCESS_ID=
    # @type=akeylessAccessKey @sensitive @internal
    AKEYLESS_ACCESS_KEY=
    ```

3. **Set your credentials in deployed environments**. Use your platform's env var management UI to securely inject these values.
</Steps>

### OIDC authentication

For deployments on platforms that issue OIDC tokens (Vercel, GitHub Actions, GitLab CI, Fly.io, GCP), you can use [OIDC workload identity federation](/guides/oidc/) to authenticate without an API key. Varlock auto-detects the platform's OIDC token and uses it to authenticate via Akeyless's OIDC access type.

**Provider-side setup:**

1. Create an OIDC auth method in Akeyless Console
2. Configure it with the deployment platform's issuer URL
3. Associate the auth method with an access role that has read permissions

**Varlock config:**
```env-spec title=".env.schema"
# @plugin(@varlock/akeyless-plugin)
# @initAkeyless(oidcAccessId="p-your-access-id")
```

No `accessKey` is needed. The `oidcAccessId` parameter triggers OIDC authentication. For platforms not auto-detected, pass an explicit token via `oidcToken`.

### Using an Akeyless Gateway

If you are running a self-hosted [Akeyless Gateway](https://docs.akeyless.io/docs/api-gateway), provide the gateway URL via the `apiUrl` parameter:

```env-spec title=".env.schema"
# @initAkeyless(
#   accessId=$AKEYLESS_ACCESS_ID,
#   accessKey=$AKEYLESS_ACCESS_KEY,
#   apiUrl="https://gateway.example.com:8080"
# )
```

### Multiple instances

If you need to connect to multiple Akeyless instances, register named instances:

```env-spec title=".env.schema"
# @initAkeyless(id=prod, accessId=$PROD_ACCESS_ID, accessKey=$PROD_ACCESS_KEY)
# @initAkeyless(id=dev, accessId=$DEV_ACCESS_ID, accessKey=$DEV_ACCESS_KEY)
# ---

PROD_SECRET=akeyless(prod, "/MyApp/Secret")
DEV_SECRET=akeyless(dev, "/MyApp/Secret")
```

## Loading secrets

Once the plugin is installed and initialized, you can start adding config items that load values using the `akeyless()` resolver function.

### Static secrets

Static secrets are simple key/value pairs. This is the default secret type.

```env-spec title=".env.schema"
# Fetch a static secret by its full path
DB_PASSWORD=akeyless("/MyApp/DB_PASSWORD")

# Extract a JSON key from a static secret storing JSON
DB_HOST=akeyless("/MyApp/DBConfig#host")

# Or use named key parameter
DB_PORT=akeyless("/MyApp/DBConfig", key="port")
```

### Path prefixing

Use `pathPrefix` to automatically prefix all secret paths for better organization:

```env-spec title=".env.schema"
# @initAkeyless(accessId=$AKEYLESS_ACCESS_ID, accessKey=$AKEYLESS_ACCESS_KEY, pathPrefix="/MyApp")
# ---

# Fetches from "/MyApp/DB_PASSWORD"
DB_PASSWORD=akeyless("DB_PASSWORD")

# Auto-infer also uses the prefix: fetches from "/MyApp/API_KEY"
API_KEY=akeyless()
```

### Dynamic secrets

Dynamic secrets generate on-demand credentials (e.g., temporary database credentials, cloud access tokens). Use the `type=dynamic` parameter:

```env-spec title=".env.schema"
# Fetch entire dynamic secret as JSON
DB_CREDENTIALS=akeyless("/MyApp/DynamicDBSecret", type=dynamic)

# Extract a specific key from the dynamic secret response
DB_USER=akeyless("/MyApp/DynamicDBSecret#user", type=dynamic)
DB_PASS=akeyless("/MyApp/DynamicDBSecret#password", type=dynamic)
```

Multiple items that reference the same dynamic secret path are cached: only one API call is made, and each item extracts its key from the cached response.

### Rotated secrets

Rotated secrets are auto-rotated credentials managed by Akeyless. Use the `type=rotated` parameter:

```env-spec title=".env.schema"
# Fetch entire rotated secret as JSON
DB_ROTATED_CREDS=akeyless("/MyApp/RotatedDBPassword", type=rotated)

# Extract individual keys from the rotated secret
DB_USER=akeyless("/MyApp/RotatedDBPassword#user", type=rotated)
DB_PASS=akeyless("/MyApp/RotatedDBPassword#password", type=rotated)
```

---

## Akeyless Setup

### Create an API Key

<Steps>
1. **Log in** to the [Akeyless Console](https://console.akeyless.io)

2. **Create an Auth Method**: Go to **Auth Methods** → **New** → **API Key**

3. **Save the credentials**: Copy the generated **Access ID** (starts with `p-`) and **Access Key**
</Steps>

### Create a static secret

You can create secrets via the Akeyless CLI or Console:

```bash
# Using the Akeyless CLI
akeyless create-secret --name "/MyApp/DB_PASSWORD" --value "supersecret"
```

Or in the Console: **Secrets & Keys** → **New** → **Static Secret**

### Set up access permissions

<Steps>
1. Go to **Access Roles** in the Akeyless Console

2. Create or edit a role and add rules to grant **read** access to the secrets your application needs

3. Associate the role with your API Key auth method
</Steps>

:::tip[Least privilege principle]
Only grant access to the specific secret paths your application needs. Avoid granting broad access to all secrets.
:::

---

## Reference

### Root decorators
<div class="reference-docs">
<div>
#### `@initAkeyless()`

Initialize an Akeyless plugin instance.

**Key/value args:**
- `accessId` (optional): Akeyless Access ID (starts with `p-` for API Key auth). Required when using API Key auth.
- `accessKey` (optional): Akeyless Access Key. Required when using API Key auth.
- `oidcAccessId` (optional): Akeyless Access ID for OIDC authentication (alternative to `accessId`/`accessKey`)
- `oidcToken` (optional): Explicit OIDC JWT token (auto-detected from platform if omitted)
- `apiUrl` (optional): Akeyless API URL (defaults to `https://api.akeyless.io`). Use this for self-hosted Akeyless Gateway.
- `pathPrefix` (optional): Prefix automatically prepended to all secret paths
- `id` (optional): Instance identifier for multiple instances
- `cacheTtl` (optional): cache resolved values for the specified duration (e.g. `"5m"`, `"1h"`, `"1d"`, or `forever` to cache until manually cleared). For cache mode behavior and CLI cache controls, see the [Caching guide](/guides/caching/). Only `static` secrets are cached. `dynamic` and `rotated` secrets change per fetch and are never cached.

```env-spec "@initAkeyless"
# @initAkeyless(accessId=$AKEYLESS_ACCESS_ID, accessKey=$AKEYLESS_ACCESS_KEY, pathPrefix="/MyApp")
```
</div>
</div>

### Data types
<div class="reference-docs">
<div>
#### `akeylessAccessId`

Represents an Akeyless Access ID for API Key authentication. Validates that the value starts with `p-`.

```env-spec "akeylessAccessId"
# @type=akeylessAccessId
AKEYLESS_ACCESS_ID=
```
</div>
<div>
#### `akeylessAccessKey`

This type is [`@internal`](/reference/item-decorators/#internal) by default: varlock uses it to fetch your other secrets but does **not** inject it into your application. Override with `@internal=false` if your app uses the credential directly, for example to write secrets back or fetch additional secrets at runtime.


Represents an Akeyless Access Key for API Key authentication. This type is marked as `@sensitive`.

```env-spec "akeylessAccessKey"
# @type=akeylessAccessKey
AKEYLESS_ACCESS_KEY=
```
</div>
</div>

### Resolver functions
<div class="reference-docs">
<div>
#### `akeyless()`

Fetch a secret from Akeyless Platform.

**Array args:**
- `instanceId` (optional): instance identifier to use when multiple plugin instances are initialized
- `secretName` (optional): full path to the secret, optionally with `#KEY` to extract a JSON key (e.g., `"/MyApp/Secret#username"`). If omitted, uses the item key (variable name) as the secret name.

**Named args:**
- `type` (optional): secret type, one of `static` (default), `dynamic`, or `rotated`
- `key` (optional): JSON key to extract from the secret value (overrides `#KEY` syntax)

**Secret types:**
- `static`: Simple key/value secrets (default). If the value is JSON, use `#KEY` or `key=` to extract individual keys.
- `dynamic`: On-demand generated credentials (database, cloud, etc.). Returns JSON by default, or extract a specific key with `#KEY` or `key=`.
- `rotated`: Auto-rotated credentials managed by Akeyless. Returns JSON by default, or extract a specific key with `#KEY` or `key=`.

**Caching:** Multiple items referencing the same secret path (and type) share a single API call. This is especially useful for dynamic and rotated secrets where you need to extract multiple keys from the same response.

```env-spec /akeyless\\(.*\\)/
# Uses item key as secret name (static)
DATABASE_URL=akeyless()

# Explicit secret path (static)
DB_PASSWORD=akeyless("/MyApp/DB_PASSWORD")

# Extract JSON key using # syntax
DB_HOST=akeyless("/MyApp/DBConfig#host")

# Extract JSON key using key= parameter
DB_PORT=akeyless("/MyApp/DBConfig", key="port")

# Dynamic secret - extract specific keys
DB_USER=akeyless("/MyApp/DynamicDB#user", type=dynamic)
DB_PASS=akeyless("/MyApp/DynamicDB#password", type=dynamic)

# Rotated secret
API_KEY=akeyless("/MyApp/RotatedKey#api_key", type=rotated)

# With instance ID
PROD_SECRET=akeyless(prod, "/MyApp/Secret")
```
</div>
</div>

---

## Troubleshooting

### Secret not found
- Verify the secret exists in the Akeyless Console
- Check the full secret path (e.g., `/MyFolder/MySecret`)
- Ensure the path starts with `/`
- If using `pathPrefix`, check the combined path is correct

### JSON key not found
- Verify the key exists in the secret value: check the Akeyless Console for the secret's content
- Key names are case-sensitive
- For static secrets, ensure the value is valid JSON when using `#KEY` or `key=`

### Permission denied
- Check the Access Role associated with your API Key auth method
- Ensure the role includes read permission for the secret path
- Verify the role is associated with the correct auth method

### Authentication failed
- Verify the Access ID starts with `p-` (API Key auth)
- Ensure the Access Key matches the Access ID
- If using a Gateway, verify the `apiUrl` is correct and reachable
- Check if the auth method is active in the Akeyless Console

## Resources

- [Akeyless Platform](https://www.akeyless.io/)
- [Akeyless Documentation](https://docs.akeyless.io/)
- [Akeyless API Key Authentication](https://docs.akeyless.io/docs/api-key)
- [Akeyless REST API Reference](https://docs.akeyless.io/reference)
- [Akeyless Gateway](https://docs.akeyless.io/docs/api-gateway)
