---
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)

## 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
    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

```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`

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 — `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)
