# How Mako's Credential Vault Protects Secrets Using OS-Level Account Boundaries

> Discover how Mako's credential vault secures secrets with OS-level account boundaries. Learn how strict filesystem permissions ensure only the owner accesses sensitive credentials.

- Repository: [The Apache Software Foundation/maka](https://github.com/apache/maka)
- Tags: security
- Published: 2026-09-06

---

**Mako's credential vault stores secrets in a plaintext JSON file protected exclusively by operating-system account isolation, using strict filesystem permissions to ensure only the owning user can access the stored credentials.**

Mako (Apache Maka) is an open-source framework for building LLM applications that require secure handling of API keys and sensitive configuration. Unlike traditional secret managers that encrypt data at rest, Mako's credential vault relies on **OS-level account boundaries** to isolate secrets, storing them in a local file with platform-specific permission controls that prevent cross-user access.

## How OS-Level Account Boundaries Work in Mako

The credential vault persists API keys and credential material in a file named [`credential-vault.json`](https://github.com/apache/maka/blob/main/credential-vault.json) located within the user's local Maka profile directory. On macOS this defaults to `~/Library/Application Support/Maka`, on Linux to `$XDG_CONFIG_HOME/Maka`, and on Windows to `%APPDATA%\Maka`. The vault itself does not encrypt the secrets; instead, it delegates access control entirely to the operating system's account isolation mechanisms.

### POSIX File Permissions (chmod 600)

On Linux and macOS systems, Mako explicitly enforces owner-only access when writing the vault file. In [`packages/storage/src/runtime-policy/document-io.ts`](https://github.com/apache/maka/blob/main/packages/storage/src/runtime-policy/document-io.ts), the `writeJsonDocument` function creates the file with mode `600` (read/write for owner only), which guarantees that no other system user can read or modify the stored secrets.

This permission is set atomically during the write operation, ensuring that even if the process is interrupted, the file never exists with relaxed permissions that could expose secrets to other users on the system.

### Windows ACL Protection

On Windows platforms, the vault relies on the default Access Control Lists (ACLs) of the `%APPDATA%` directory tree. When Maka creates the profile directory and vault file within the current user's local application data folder, Windows automatically applies ACLs that restrict access solely to the logged-in user account. This provides equivalent isolation to the POSIX permission model without requiring explicit chmod operations.

## Vault Safeguards and Limitations

Beyond OS-level account boundaries, the vault implementation includes several safeguards to prevent abuse and corruption, implemented in [`packages/storage/src/runtime-policy/credential-vault-document.ts`](https://github.com/apache/maka/blob/main/packages/storage/src/runtime-policy/credential-vault-document.ts).

### Size and Entry Limits

The `CredentialVaultDocumentOwner` class enforces strict bounds on vault contents to prevent accidental oversizing or denial-of-service scenarios:

- **Maximum secret length**: Individual secrets are limited to 64 KB (`MAX_SECRET_LENGTH = 64 * 1024`), validated by the `assertCredentialInputSecretLimit` function
- **Maximum entries**: The vault cannot exceed 2,048 credentials (`MAX_VAULT_ENTRIES = 2_048`)
- **Document size**: The entire JSON document must remain under the byte limit defined by `VAULT_DOCUMENT_MAX_BYTES`, checked via `assertDocumentSize`

These limits ensure that the vault file remains manageable and that memory exhaustion attacks cannot exploit the storage system.

### Atomic Write Operations

All modifications to the vault use atomic write semantics implemented in `writeJsonDocument`. The process writes data to a temporary file first, then renames it to the target filename. This prevents partial writes that could leave the vault in a corrupted state if the process crashes or the system loses power during a credential update.

## Working with the Credential Vault

The `CredentialVaultDocumentOwner` class in [`credential-vault-document.ts`](https://github.com/apache/maka/blob/main/credential-vault-document.ts) provides the primary API for interacting with the vault. The following examples demonstrate how to store, retrieve, and delete credentials while maintaining OS-level protection.

### Storing a New Credential

```typescript
import { CredentialVaultDocumentOwner } from '@maka/storage/runtime-policy/credential-vault-document';
import type { SetCredentialInput } from '@maka/core/runtime-policy';

// `profileRoot` points to the Maka profile directory
const vault = new CredentialVaultDocumentOwner();

const input: SetCredentialInput = {
  locator: {
    scope: 'connection',
    kind: 'api_key',
    connectionId: 'openai-connection',
  },
  secret: 'sk-xxxxxxxxxxxxxxxxxxxx',
  expected: null, // No prior expectation
};

await vault.set(profileRoot, input);

```

When executed on POSIX systems, the `set` method writes to [`credential-vault.json`](https://github.com/apache/maka/blob/main/credential-vault.json) with `chmod 600` permissions. On Windows, it relies on the inherited ACLs from `%APPDATA%` to restrict access.

### Reading a Credential

```typescript
import { CredentialVaultDocumentOwner } from '@maka/storage/runtime-policy/credential-vault-document';
import type { CredentialLocator } from '@maka/core/runtime-policy';

const vault = new CredentialVaultDocumentOwner();
const doc = await vault.read(profileRoot);

const locator: CredentialLocator = {
  scope: 'connection',
  kind: 'api_key',
  connectionId: 'openai-connection',
};

const entry = doc.entries.find(e => e.locator.connectionId === locator.connectionId);
if (entry) {
  console.log('Secret:', entry.secret); // Accessible only to the same OS user
}

```

Because the file permissions restrict read access to the owning user account, any attempt to execute this code under a different system user will fail with a permission error, even if the attacker knows the exact file path.

### Deleting a Credential

```typescript
import { CredentialVaultDocumentOwner } from '@maka/storage/runtime-policy/credential-vault-document';
import type { DeleteCredentialInput } from '@maka/core/runtime-policy';

const vault = new CredentialVaultDocumentOwner();

const delInput: DeleteCredentialInput = {
  expected: {
    locator: {
      scope: 'connection',
      kind: 'api_key',
      connectionId: 'openai-connection',
    },
    credentialId: 'a1b2c3d4-…',
    revision: 3,
  },
};

await vault.delete(profileRoot, delInput);

```

Deletes are performed atomically, ensuring the vault file is never left in an inconsistent state.

## Security Model Implications

As documented in the CLI README (lines 87-90), the Maka project explicitly states: "The current credential vault is a local plaintext file protected by the operating-system account boundary; on POSIX systems Maka enforces owner-only directory and file modes. It is not an OS keychain."

This design choice provides several advantages:

- **No external dependencies**: The vault does not require keychain services, GNOME Keyring, or macOS Keychain, simplifying deployment across headless servers and containers
- **Strong isolation**: Processes running under different user accounts cannot access the secrets, even with file path knowledge
- **Predictable behavior**: The security model relies on well-understood filesystem permissions rather than complex encryption key management

However, users should note that this model provides no protection against physical disk theft or forensic analysis of unencrypted drives, as the secrets remain plaintext within the file.

## Summary

- Mako's credential vault stores secrets in a plaintext JSON file located in the user profile directory ([`credential-vault.json`](https://github.com/apache/maka/blob/main/credential-vault.json))
- **OS-level account boundaries** protect the vault through `chmod 600` on POSIX systems and Windows ACLs on Windows platforms
- The vault enforces strict limits: 64 KB maximum secret size, 2,048 maximum entries, and bounded document size
- All writes are atomic, using temporary files and rename operations to prevent corruption
- Only the operating system user who owns the profile can read or modify credentials, as enforced by filesystem permissions in [`document-io.ts`](https://github.com/apache/maka/blob/main/document-io.ts)

## Frequently Asked Questions

### Does Mako encrypt the credential vault file?

No, the vault file is stored as plaintext JSON without encryption. According to the Apache Maka source code, the vault relies entirely on **OS-level account boundaries**—specifically file permissions on POSIX systems (`chmod 600`) and Windows ACLs—to prevent unauthorized access. This design explicitly avoids encryption to eliminate dependencies on external keychain services.

### What happens if another user tries to read the credential vault?

Any process running under a different operating system user account will receive a permission denied error when attempting to access [`credential-vault.json`](https://github.com/apache/maka/blob/main/credential-vault.json). On Linux and macOS, the `writeJsonDocument` function in [`document-io.ts`](https://github.com/apache/maka/blob/main/document-io.ts) sets the file mode to owner-only (600), while Windows inherits restrictive ACLs from the `%APPDATA%` user directory. This ensures secrets remain inaccessible to other local users.

### Is there a limit to how many secrets I can store in the vault?

Yes, the `CredentialVaultDocumentOwner` class enforces a maximum of 2,048 entries (`MAX_VAULT_ENTRIES = 2_048`) and individual secrets cannot exceed 64 KB (`MAX_SECRET_LENGTH = 64 * 1024`). Additionally, the entire vault document must stay under the byte limit checked by `assertDocumentSize`. These constraints prevent the vault from consuming excessive disk space or memory.

### Why doesn't Mako use the OS keychain instead of a plaintext file?

The Maka project intentionally avoids OS keychain dependencies to simplify deployment across diverse environments, including headless servers, containers, and CI/CD pipelines where keychain daemons may not be available. The current implementation prioritizes portability and simplicity while maintaining security through strict **OS-level account boundaries** enforced by filesystem permissions.