Please check the build logs for more information.
See Builds for ideas on how to fix a failed build, or Metadata for how to configure docs.rs builds.
If you believe this is docs.rs' fault, open an issue.
cuenv
A direnv alternative that uses CUE packages for environment configuration.
Development
Development is only supported through the Nix flake:
# Enter the development shell
# Build the project
Installation
Using Nix (Recommended)
# Install directly from the GitHub repository
# Or run without installing
# Using a specific version/commit
Home Manager Module
If you're using Home Manager, you can use the included module:
# In your flake.nix
{
inputs = {
cuenv.url = "github:rawkode/cuenv";
# ... other inputs
};
outputs = { self, nixpkgs, home-manager, cuenv, ... }: {
homeConfigurations.yourUsername = home-manager.lib.homeManagerConfiguration {
# ... your configuration
modules = [
cuenv.homeManagerModules.default
{
programs.cuenv = {
enable = true;
# Optional: specify package
# package = cuenv.packages.${pkgs.system}.default;
# Shell integrations (auto-detected based on enabled shells)
# enableBashIntegration = true;
# enableZshIntegration = true;
# enableFishIntegration = true;
# enableNushellIntegration = true; # Experimental
};
}
];
};
};
}
The module will automatically:
- Install the cuenv package
- Set up shell integration for enabled shells (bash, zsh, fish, nushell)
- Configure the shell hooks to load CUE environments automatically
Using Cargo
# Install from crates.io
Building from Source
# Clone the repository
# Build with Nix
# The binary will be available in ./result/bin/cuenv
Setup
Add the following to your shell configuration:
Bash (~/.bashrc)
Zsh (~/.zshrc)
Fish (~/.config/fish/config.fish)
cuenv init fish | source
Usage
- Create a CUE package in your project directory with
.cuefiles:
package env
import "github.com/rawkode/cuenv"
env: cuenv.#Env & {
DATABASE_URL: "postgres://localhost/mydb"
API_KEY: "secret123"
DEBUG: "true"
PORT: "3000"
}
- Navigate to the directory and the environment will be automatically loaded.
Commands
cuenv- Load CUE package from current directorycuenv load [directory]- Manually load environment from a directorycuenv unload- Unload the current environmentcuenv status- Show environment changescuenv hook <shell>- Generate shell-specific hook outputcuenv init <shell>- Generate shell initialization scriptcuenv run <command> [args...]- Run a command in a hermetic environment with only CUE-defined variables
Features
- Automatic environment loading when entering directories
- CUE package-based environment loading
- Shell variable expansion support
- Support for multiple shells (bash, zsh, fish)
- Type-safe configuration with CUE
- Secret resolution from 1Password and GCP Secrets Manager (with
cuenv run) - Automatic secret obfuscation in stdout/stderr to prevent accidental exposure
- Environment-specific configurations with inheritance
- Capability-based variable filtering for secure credential management
- Command inference for automatic capability detection
- Environment variable configuration (CUENV_ENV, CUENV_CAPABILITIES)
CUE File Format
Your CUE package should use the cuenv package schema:
package env
import "github.com/rawkode/cuenv"
env: cuenv.#Env & {
// String values
DATABASE_URL: "postgres://user:pass@host/db"
// String representations of numbers
PORT: "3000"
TIMEOUT: "30"
// String representations of booleans
DEBUG: "true"
ENABLE_CACHE: "false"
// Shell expansion is supported
LOG_PATH: "$HOME/logs/myapp"
// CUE features are supported
BASE_URL: "https://api.example.com"
API_ENDPOINT: "\(BASE_URL)/v1" // String interpolation
HOST: "localhost"
DATABASE_DSN: "postgres://\(HOST):5432/myapp" // Computed values
}
How It Works
- When you cd into a directory, cuenv checks for CUE packages (directories with
.cuefiles) - It loads the CUE package from the current directory
- Environment variables are set in your shell
- When you leave the directory, the environment is restored
Running Commands in Hermetic Environment
The run command executes programs with only the environment variables defined in your CUE files (plus PATH and HOME for basic functionality):
# Run a command with CUE-defined environment
# Pass arguments to the command
# Run shell commands
# The environment is hermetic - parent environment variables are not passed through
Access Restrictions
You can configure disk and network access restrictions for tasks using the security section in your CUE task definitions. This uses Landlock (Linux Security Module) for enforcement:
tasks: {
"secure-build": {
description: "Build the project with restricted filesystem access"
command: "echo 'Building project securely...' && sleep 1 && echo 'Build complete!'"
security: {
restrictDisk: true
readOnlyPaths: ["/usr", "/lib", "/bin"]
readWritePaths: ["/tmp", "./build"]
}
}
"network-task": {
description: "Task that needs network access but with restrictions"
command: "echo 'Downloading dependencies...' && curl --version"
security: {
restrictNetwork: true
allowedHosts: ["api.example.com", "registry.npmjs.org"]
}
}
"fully-restricted": {
description: "Task with both disk and network restrictions"
command: "echo 'Running in secure sandbox'"
security: {
restrictDisk: true
restrictNetwork: true
readOnlyPaths: ["/usr/bin", "/bin"]
readWritePaths: ["/tmp"]
allowedHosts: ["localhost"]
}
}
"unrestricted": {
description: "Task without security restrictions"
command: "echo 'Running without restrictions' && ls -la /"
}
}
Running tasks with security restrictions:
# Run a task with disk restrictions
# Run a task with network restrictions
# Run a fully restricted task
Landlock Requirements:
- Linux kernel 5.13+ (for filesystem restrictions)
- Linux kernel 5.19+ (for network restrictions - basic support)
- Appropriate permissions to use Landlock LSM
Security Configuration Options:
restrictDisk: Enable filesystem access restrictionsrestrictNetwork: Enable network access restrictionsreadOnlyPaths: Array of paths allowed for readingreadWritePaths: Array of paths allowed for reading and writingdenyPaths: Array of paths explicitly denied (overrides allow lists)allowedHosts: Array of network hosts/CIDRs allowed for connections
Security Model: When disk restrictions are enabled, you must explicitly allow all paths your task needs access to. This includes:
- Executable paths (
/bin,/usr/bin) - Library paths (
/lib,/usr/lib,/lib64,/usr/lib64) - Configuration paths (
/etcif needed) - Working directories and output paths
Note: Network restrictions are currently limited by Landlock V2 capabilities. The implementation will be enhanced in future versions to provide more granular network access control.
Note: Network and process restrictions are not yet fully implemented with Landlock. Use system-level controls or container runtimes for those restrictions.
Secret Resolution
When using cuenv run, secret references in your CUE files are automatically resolved:
package env
import "github.com/rawkode/cuenv"
env: cuenv.#Env & {
// Regular environment variables
DATABASE_HOST: "localhost"
DATABASE_USER: "myapp"
// Secret references - 1Password format
DATABASE_PASSWORD: cuenv.#OnePasswordRef & {ref: "op://Personal/database/password"}
API_KEY: cuenv.#OnePasswordRef & {ref: "op://Work/myapp-api-key/field"}
// Secret references - Various providers
GITHUB_TOKEN: "github://myorg/myrepo/GITHUB_TOKEN"
AWS_SECRET: "aws-secret://prod/api/secret"
GCP_SECRET: "gcp-secret://myproject/db-password"
AZURE_KEY: "azure-keyvault://myvault/keys/mykey"
VAULT_TOKEN: "vault://secret/data/myapp/token"
// You can compose URLs with resolved secrets
DB_HOST: "prod.example.com"
DATABASE_URL: "postgres://\(DATABASE_USER):\(DATABASE_PASSWORD)@\(DB_HOST):5432/myapp"
}
Requirements:
- For 1Password: Install 1Password CLI and authenticate with
op signin - For GCP Secrets: Install gcloud CLI and authenticate with
gcloud auth login
Note: Secret resolution only happens with cuenv run. Regular cuenv load will not resolve secrets for security reasons.
Secret Obfuscation
When using cuenv run, any resolved secret values are automatically obfuscated in the command's stdout and stderr output. This prevents accidental exposure of sensitive information in logs or terminal output.
# Example: If DATABASE_PASSWORD resolves to "secret123"
# Output: Password is: ***********
# Secrets are obfuscated even in error messages
# Stderr: Error: Failed to connect with ***********
This obfuscation applies to all resolved secrets from 1Password and GCP Secrets Manager, helping maintain security when running commands with sensitive data.
Environments and Capabilities
cuenv supports environment-specific configurations and capability-based filtering:
package env
import "github.com/rawkode/cuenv"
env: cuenv.#Env & {
// Base configuration
DATABASE_URL: "postgresql://localhost:5432/myapp"
LOG_LEVEL: "info"
PORT: "3000"
// AWS capabilities - tagged with @capability
AWS_REGION: "us-east-1" @capability("aws")
AWS_ACCESS_KEY: "aws-access-key" @capability("aws")
AWS_SECRET_KEY: "aws-secret-key" @capability("aws")
// Docker capabilities
DOCKER_REGISTRY: "docker.io" @capability("docker")
DOCKER_IMAGE: "myapp:latest" @capability("docker")
// Environment-specific overrides
environment: {
production: {
DATABASE_URL: "postgresql://prod-db:5432/myapp"
LOG_LEVEL: "warn"
PORT: "8080"
AWS_REGION: "us-west-2" @capability("aws")
}
staging: {
DATABASE_URL: "postgresql://staging-db:5432/myapp"
LOG_LEVEL: "debug"
}
}
// Capability mappings for automatic inference
capabilities: {
aws: {
commands: ["terraform", "aws", "deploy"]
}
cloudflare: {
commands: ["terraform"]
}
docker: {
commands: ["deploy"]
}
}
}
Usage:
# Use production environment
# Enable specific capabilities
# Use environment variables
CUENV_ENV=production CUENV_CAPABILITIES=aws
# Automatic capability inference from command
Documentation
- Quickstart Guide - Get started quickly with cuenv
- Commands Reference - Complete command reference
- Secret Management - Secret management and security guide
- CUE Format Guide - Type-safe configuration with CUE
- Environments - Environment-specific configurations
- Capabilities - Capability-based variable filtering
- Shell Integration - Setting up shell hooks
- Configuration - Configuration options reference
- Environment Variables - Using environment variables for configuration
Differences from direnv
- Uses CUE instead of shell scripts for configuration
- Type-safe configuration files
- No need for
direnv allow(can be added if needed) - Simpler mental model - just key-value pairs in CUE format