SDKs & Integrations
Ruby SDK
Official Ruby SDK for KeyEnv.
Ruby SDK
Official Ruby SDK for KeyEnv with Ruby 3.0+ support.
Beta Release: This SDK is currently in development. APIs may change before the stable 1.0 release.
Installation
Add to your Gemfile:
gem 'keyenv'Then run:
bundle installOr install directly:
gem install keyenvQuick Start
require 'keyenv'
client = KeyEnv::Client.new(token: ENV['KEYENV_TOKEN'])
# Load secrets into ENV
count = client.load_env(project_id: 'your-project-id', environment: 'production')
puts "Loaded #{count} secrets"
# Access secrets
puts ENV['DATABASE_URL']Initialize the Client
Simple Initialization
require 'keyenv'
client = KeyEnv::Client.new(token: ENV['KEYENV_TOKEN'])With Options
client = KeyEnv::Client.new(
token: ENV['KEYENV_TOKEN'],
timeout: 60, # Request timeout in seconds (default: 30)
cache_ttl: 300 # Cache TTL in seconds (default: 0 = disabled)
)Loading Secrets
Load into ENV
The simplest way to use secrets in your application:
count = client.load_env(project_id: 'project-id', environment: 'production')
puts "Loaded #{count} secrets"
# Access via ENV
puts ENV['DATABASE_URL']
puts ENV['API_KEY']Get Secrets as Hash
Get secrets as a key-value hash:
secrets = client.export_secrets_as_hash(project_id: 'project-id', environment: 'production')
puts secrets['DATABASE_URL']
puts secrets['API_KEY']Export as Array
Get secrets with metadata:
secrets = client.export_secrets(project_id: 'project-id', environment: 'production')
secrets.each do |secret|
puts "#{secret.key}=#{secret.value}"
endManaging Secrets
Get a Single Secret
secret = client.get_secret(project_id: 'project-id', environment: 'production', key: 'DATABASE_URL')
puts secret.value
puts secret.descriptionSet a Secret
Creates or updates a secret:
client.set_secret(
project_id: 'project-id',
environment: 'production',
key: 'API_KEY',
value: 'sk_live_...'
)
# With description
client.set_secret(
project_id: 'project-id',
environment: 'production',
key: 'API_KEY',
value: 'sk_live_...',
description: 'Production API key'
)Create a Secret
Explicitly create a new secret:
secret = client.create_secret(
project_id: 'project-id',
environment: 'production',
key: 'NEW_KEY',
value: 'new_value',
description: 'New secret'
)Update a Secret
Explicitly update an existing secret:
secret = client.update_secret(
project_id: 'project-id',
environment: 'production',
key: 'EXISTING_KEY',
value: 'updated_value'
)Delete a Secret
client.delete_secret(project_id: 'project-id', environment: 'production', key: 'OLD_KEY')Bulk Operations
Bulk Import
Import multiple secrets at once:
result = client.bulk_import(
project_id: 'project-id',
environment: 'development',
secrets: [
{ key: 'DATABASE_URL', value: 'postgres://localhost/mydb' },
{ key: 'REDIS_URL', value: 'redis://localhost:6379' },
{ key: 'API_KEY', value: 'sk_test_...', description: 'Test API key' }
],
overwrite: true
)
puts "Created: #{result.created}, Updated: #{result.updated}"Generate .env File
env_content = client.generate_env_file(project_id: 'project-id', environment: 'production')
File.write('.env', env_content)Projects & Environments
List Projects
projects = client.list_projects
projects.each do |project|
puts "#{project.name} (#{project.id})"
endGet Project Details
project = client.get_project(project_id: 'project-id')
puts "Project: #{project.name}"
project.environments.each do |env|
puts " - #{env.name}"
endList Environments
environments = client.list_environments(project_id: 'project-id')
environments.each do |env|
puts env.name
endEnvironment Permissions
List Permissions
permissions = client.list_permissions(project_id: 'project-id', environment: 'production')
permissions.each do |perm|
puts "#{perm.user_email}: #{perm.role}"
endSet Permission
client.set_permission(
project_id: 'project-id',
environment: 'production',
user_id: 'user-id',
role: 'write'
)Get My Permissions
permissions, is_team_admin = client.get_my_permissions(project_id: 'project-id')
permissions.each do |perm|
puts "#{perm.environment_name}: #{perm.role} (can_write: #{perm.can_write})"
endCaching
Enable caching for better performance in high-throughput applications:
client = KeyEnv::Client.new(
token: ENV['KEYENV_TOKEN'],
cache_ttl: 300 # 5 minutes
)
# First call fetches from API
client.export_secrets(project_id: 'project-id', environment: 'production')
# Subsequent calls within TTL use cache
client.export_secrets(project_id: 'project-id', environment: 'production')
# Clear cache when needed
client.clear_cache(project_id: 'project-id', environment: 'production')
client.clear_cache # Clear allError Handling
require 'keyenv'
begin
secret = client.get_secret(project_id: 'project-id', environment: 'production', key: 'MISSING_KEY')
rescue KeyEnv::AuthenticationError => e
puts "Invalid or expired token: #{e.message}"
rescue KeyEnv::NotFoundError => e
puts "Secret not found: #{e.message}"
rescue KeyEnv::ValidationError => e
puts "Validation error: #{e.message}"
puts "Details: #{e.details}" if e.details
rescue KeyEnv::RateLimitError => e
puts "Rate limited, try again later"
rescue KeyEnv::Error => e
puts "Error #{e.status}: #{e.message}"
endAPI Reference
Constructor Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
token | String | Yes | - | Service token |
timeout | Integer | No | 30 | Request timeout (seconds) |
cache_ttl | Integer | No | 0 | Cache TTL (0 disables) |
Methods
| Method | Description |
|---|---|
get_current_user | Get current user/token info |
validate_token | Validate token and get user info |
list_projects | List all accessible projects |
get_project(project_id:) | Get project with environments |
list_environments(project_id:) | List environments in a project |
list_secrets(project_id:, environment:) | List secret keys (no values) |
export_secrets(project_id:, environment:) | Export secrets with values |
export_secrets_as_hash(project_id:, environment:) | Export as hash |
get_secret(project_id:, environment:, key:) | Get single secret |
create_secret(project_id:, environment:, key:, value:) | Create new secret |
update_secret(project_id:, environment:, key:, value:) | Update existing secret |
set_secret(project_id:, environment:, key:, value:) | Create or update secret |
delete_secret(project_id:, environment:, key:) | Delete secret |
bulk_import(project_id:, environment:, secrets:) | Bulk import secrets |
load_env(project_id:, environment:) | Load secrets into ENV |
generate_env_file(project_id:, environment:) | Generate .env file content |
list_permissions(project_id:, environment:) | List permissions |
set_permission(project_id:, environment:, user_id:, role:) | Set permission |
delete_permission(project_id:, environment:, user_id:) | Delete permission |
get_my_permissions(project_id:) | Get current user's permissions |
get_project_defaults(project_id:) | Get default permissions |
set_project_defaults(project_id:, defaults:) | Set default permissions |
clear_cache | Clear secrets cache |
Examples
Rails Application
# config/initializers/keyenv.rb
if ENV['KEYENV_TOKEN'].present?
client = KeyEnv::Client.new(token: ENV['KEYENV_TOKEN'])
client.load_env(
project_id: ENV['KEYENV_PROJECT'],
environment: Rails.env
)
endRails with Credentials
# config/initializers/keyenv.rb
if Rails.application.credentials.keyenv&.token
client = KeyEnv::Client.new(token: Rails.application.credentials.keyenv.token)
client.load_env(
project_id: Rails.application.credentials.keyenv.project,
environment: Rails.env
)
endSinatra Application
require 'sinatra'
require 'keyenv'
# Load secrets at startup
if ENV['KEYENV_TOKEN']
client = KeyEnv::Client.new(token: ENV['KEYENV_TOKEN'])
client.load_env(project_id: ENV['KEYENV_PROJECT'], environment: 'production')
end
get '/' do
{ status: 'ok' }.to_json
end
get '/config' do
content_type :json
{
api_url: ENV['API_URL']
# Don't expose sensitive secrets!
}.to_json
endSidekiq Worker
# config/initializers/sidekiq.rb
Sidekiq.configure_server do |config|
if ENV['KEYENV_TOKEN']
client = KeyEnv::Client.new(
token: ENV['KEYENV_TOKEN'],
cache_ttl: 300 # Cache for 5 minutes
)
client.load_env(project_id: ENV['KEYENV_PROJECT'], environment: Rails.env)
end
endRake Task
# lib/tasks/secrets.rake
namespace :secrets do
desc 'Sync secrets from KeyEnv to .env file'
task :sync do
require 'keyenv'
token = ENV['KEYENV_TOKEN'] || raise('KEYENV_TOKEN not set')
project = ENV['KEYENV_PROJECT'] || raise('KEYENV_PROJECT not set')
env = ENV['RAILS_ENV'] || 'development'
client = KeyEnv::Client.new(token: token)
content = client.generate_env_file(project_id: project, environment: env)
File.write('.env', content)
puts "Synced secrets to .env"
end
endRSpec Test Setup
# spec/support/keyenv.rb
RSpec.configure do |config|
config.before(:suite) do
if ENV['KEYENV_TOKEN']
client = KeyEnv::Client.new(token: ENV['KEYENV_TOKEN'])
client.load_env(project_id: ENV['KEYENV_PROJECT'], environment: 'test')
end
end
endAWS Lambda with Ruby
require 'keyenv'
# Initialize client outside handler for reuse across invocations
$keyenv_client = KeyEnv::Client.new(
token: ENV['KEYENV_TOKEN'],
cache_ttl: 300 # Cache for 5 minutes in warm lambdas
)
def handler(event:, context:)
# Load secrets (cached after first invocation)
$keyenv_client.load_env(
project_id: ENV['KEYENV_PROJECT'],
environment: 'production'
)
# Your handler logic here
{
statusCode: 200,
body: JSON.generate({ message: 'Success' })
}
end