@stain-win/gaia-client
v0.0.1-rc.9
Published
TypeScript/JavaScript client library for Gaia secret management daemon
Downloads
35
Maintainers
Readme
'@stain-win/gaia-client'
TypeScript/JavaScript client library for Gaia - a secure, self-hosted secret management daemon.
Installation
npm install '@stain-win/gaia-client'Quick Start
import { createClient } from @stain-win/gaia-client';
// Connect to Gaia daemon
const client = await createClient({
address: 'localhost:50051',
caCertFile: './certs/ca.crt',
clientCertFile: './certs/client.crt',
clientKeyFile: './certs/client.key'
});
try {
// Fetch a secret
const dbUrl = await client.getSecret('production', 'database_url');
console.log('Database URL:', dbUrl);
// Get all common secrets
const secrets = await client.getCommonSecrets();
console.log('All secrets:', secrets);
// Load secrets into environment variables
await client.loadEnv();
// Now accessible as: process.env.GAIA_PRODUCTION_DATABASE_URL
} finally {
await client.close();
}API Reference
createClient(config: GaiaClientConfig): Promise<GaiaClient>
Creates and connects a Gaia client in one step.
Parameters:
config.address(string, required): Address of the Gaia gRPC server (e.g., "localhost:50051")config.caCertFile(string, optional): Path to the CA certificate fileconfig.clientCertFile(string, optional): Path to the client's certificate fileconfig.clientKeyFile(string, optional): Path to the client's private key fileconfig.timeout(number, optional): Connection timeout in milliseconds (default: 5000)config.insecure(boolean, optional): Allow insecure connections (default: false, for development only)
Returns: Connected GaiaClient instance
Example:
const client = await createClient({
address: 'localhost:50051',
caCertFile: './certs/ca.crt',
clientCertFile: './certs/client.crt',
clientKeyFile: './certs/client.key',
timeout: 10000
});GaiaClient
High-level client for interacting with the Gaia daemon.
Constructor
new GaiaClient(config: GaiaClientConfig)Creates a new Gaia client. You must call connect() before using other methods.
Methods
connect(): Promise<void>
Establishes connection to the Gaia daemon.
const client = new GaiaClient(config);
await client.connect();getSecret(namespace: string, id: string): Promise<string>
Fetches a single secret from a specific namespace.
Parameters:
namespace: The namespace containing the secretid: The secret ID
Returns: The secret value
Example:
const apiKey = await client.getSecret('production', 'api_key');getCommonSecrets(namespace?: string): Promise<SecretsMap>
Fetches secrets from the "common" area.
Parameters:
namespace(optional): If provided, returns secrets only for this namespace
Returns: Map of namespace names to their secrets (key-value pairs)
Example:
// Get all common secrets
const allSecrets = await client.getCommonSecrets();
// { production: { api_key: '...', db_url: '...' }, staging: { ... } }
// Get secrets from specific namespace
const prodSecrets = await client.getCommonSecrets('production');
// { production: { api_key: '...', db_url: '...' } }loadEnv(options?: LoadEnvOptions): Promise<void>
Loads all accessible secrets into process.env.
By default, environment variables are named directly after the secret key.
- Key names are uppercased
- Hyphens are replaced with underscores
You can optionally configure a prefix or include the namespace via options.
Example:
// Load with default behavior (key only)
await client.loadEnv();
// Secrets are now available as environment variables:
console.log(process.env.DATABASE_URL);
console.log(process.env.API_KEY);
// To load with a custom prefix and namespace included:
// await client.loadEnv({ prefix: 'GAIA', useNamespace: true });
// console.log(process.env.GAIA_PRODUCTION_DATABASE_URL);getStatus(): Promise<string>
Checks the current operational status of the Gaia daemon.
Returns: Status string (e.g., "locked", "unlocked", "offline")
Example:
const status = await client.getStatus();
console.log('Daemon status:', status);getNamespaces(): Promise<string[]>
Lists all namespaces the authenticated client has access to.
Returns: Array of namespace names
Example:
const namespaces = await client.getNamespaces();
console.log('Available namespaces:', namespaces);
// ['common', 'production', 'staging']listSecrets(namespace?: string): Promise<SecretsMap> ⭐ NEW
Lists all secrets for the authenticated client, including both the client's own namespaces and the common namespace. This is the most efficient method for fetching all secrets at once.
Parameters:
namespace(optional): If provided, returns secrets only for this namespace
Returns: Map of namespace names to their secrets (key-value pairs)
Example:
// Get all secrets (client's own + common)
const allSecrets = await client.listSecrets();
// {
// common: { shared_key: '...' },
// production: { api_key: '...', db_url: '...' },
// staging: { api_key: '...' }
// }
// Get secrets from specific namespace only
const prodSecrets = await client.listSecrets('production');
// { production: { api_key: '...', db_url: '...' } }
// Iterate through all secrets
for (const [namespace, secrets] of Object.entries(allSecrets)) {
console.log(`Namespace: ${namespace}`);
for (const [key, value] of Object.entries(secrets)) {
console.log(` ${key}: ${value}`);
}
}Note: This is the recommended method for bulk secret retrieval, as it makes a single RPC call instead of multiple requests.
close(): Promise<void>
Closes the connection to the Gaia daemon. Should be called when done.
await client.close();TypeScript Types
interface GaiaClientConfig {
address: string;
caCertFile?: string;
clientCertFile?: string;
clientKeyFile?: string;
timeout?: number;
insecure?: boolean;
}
interface Secret {
id: string;
value: string;
}
interface Namespace {
name: string;
secrets: Secret[];
}
type SecretsMap = Record<string, Record<string, string>>;Advanced Usage
Manual Connection Management
import { GaiaClient } from ''@stain-win/gaia-client'';
const client = new GaiaClient({
address: 'localhost:50051',
caCertFile: './certs/ca.crt',
clientCertFile: './certs/client.crt',
clientKeyFile: './certs/client.key'
});
try {
await client.connect();
// Use client...
const secret = await client.getSecret('production', 'api_key');
} catch (error) {
console.error('Failed:', error);
} finally {
await client.close();
}Insecure Connection (Development Only)
const client = await createClient({
address: 'localhost:50051',
insecure: true // WARNING: For development only!
});Error Handling
try {
const secret = await client.getSecret('production', 'api_key');
} catch (error) {
if (error.code === grpc.status.NOT_FOUND) {
console.error('Secret not found');
} else if (error.code === grpc.status.PERMISSION_DENIED) {
console.error('Access denied');
} else {
console.error('Error:', error.message);
}
}Using with Express.js
import express from 'express';
import { createClient } from ''@stain-win/gaia-client'';
const app = express();
// Load secrets on startup
const client = await createClient({
address: 'localhost:50051',
caCertFile: './certs/ca.crt',
clientCertFile: './certs/client.crt',
clientKeyFile: './certs/client.key'
});
await client.loadEnv();
// Access secrets via environment variables
const dbUrl = process.env.GAIA_PRODUCTION_DATABASE_URL;
app.listen(3000, () => {
console.log('Server started');
});
// Cleanup on shutdown
process.on('SIGTERM', async () => {
await client.close();
process.exit(0);
});Requirements
- Node.js >= 14.x
- Gaia daemon running and accessible
- Valid mTLS certificates (unless using insecure mode)
License
MIT
