KeyEnvKeyEnv
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 install

Or install directly:

gem install keyenv

Quick 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}"
end

Managing Secrets

Get a Single Secret

secret = client.get_secret(project_id: 'project-id', environment: 'production', key: 'DATABASE_URL')
puts secret.value
puts secret.description

Set 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})"
end

Get Project Details

project = client.get_project(project_id: 'project-id')
puts "Project: #{project.name}"
project.environments.each do |env|
  puts "  - #{env.name}"
end

List Environments

environments = client.list_environments(project_id: 'project-id')
environments.each do |env|
  puts env.name
end

Environment Permissions

List Permissions

permissions = client.list_permissions(project_id: 'project-id', environment: 'production')
permissions.each do |perm|
  puts "#{perm.user_email}: #{perm.role}"
end

Set 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})"
end

Caching

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 all

Error 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}"
end

API Reference

Constructor Parameters

ParameterTypeRequiredDefaultDescription
tokenStringYes-Service token
timeoutIntegerNo30Request timeout (seconds)
cache_ttlIntegerNo0Cache TTL (0 disables)

Methods

MethodDescription
get_current_userGet current user/token info
validate_tokenValidate token and get user info
list_projectsList 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_cacheClear 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
  )
end

Rails 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
  )
end

Sinatra 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
end

Sidekiq 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
end

Rake 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
end

RSpec 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
end

AWS 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

On this page