How Mako's Credential Vault Protects Secrets Using OS-Level Account Boundaries
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 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, 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.
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 theassertCredentialInputSecretLimitfunction - 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 viaassertDocumentSize
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 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
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 with chmod 600 permissions. On Windows, it relies on the inherited ACLs from %APPDATA% to restrict access.
Reading a Credential
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
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) - OS-level account boundaries protect the vault through
chmod 600on 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
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. On Linux and macOS, the writeJsonDocument function in 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.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →