The project is in a healthy, maintained state
A small, dependency-free gem that encrypts and decrypts a single credentials.yml.enc file with AES-256-GCM. Ships an `mcr` command line tool for reading and writing values, plus a Ruby API. Designed for container and server workflows where the encrypted file travels with the image and the master key is injected at runtime via MAQUINA_MASTER_KEY.
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
 Dependencies

Development

>= 0
~> 5.16
~> 13.0
~> 1.55
 Project Readme

Maquina Credentials

Encrypt and decrypt a single credentials.yml.enc file with AES-256-GCM.

maquina_credentials is a small, dependency-free gem for storing secrets in an encrypted file that can safely travel with your source or container image. The master key never lives in the file — it is supplied at runtime through the MAQUINA_MASTER_KEY environment variable. Reading a missing key returns an empty string and never raises, so it is safe to call in code paths that may run without credentials configured.

It is inspired by Rails' encrypted credentials, distilled down to a single file, a command line tool, and a plain Ruby API — with no dependency on Rails or Active Support.

Installation

Add it to your Gemfile:

gem "maquina_credentials"

Then run bundle install. Or install it directly:

gem install maquina_credentials

Requires Ruby >= 3.2.0.

Master key

Generate a master key once and store it as a secret (never commit it):

mcr generate

This prints a fresh random key built from SecureRandom.hex(32). If you do not have the executable handy, the equivalent in plain Ruby is:

ruby -e "require 'securerandom'; puts SecureRandom.hex(32)"

Provide the key to every command through MAQUINA_MASTER_KEY. Any 32-byte key is used directly; keys of any other length (including the 64-character hex string above) are run through HKDF-SHA256 to derive the encryption key.

Command line

The gem installs an mcr executable.

Read a value (dot-paths traverse nested keys):

MAQUINA_MASTER_KEY=<key> mcr read database.password

Write credentials from piped YAML:

MAQUINA_MASTER_KEY=<key> printf "database:\n  password: prod-secret\n" | mcr write

Use a specific encrypted file:

mcr --file /path/to/credentials.yml.enc read database.password

Generate a new master key:

mcr generate

Show help:

mcr help

File selection

The encrypted file is resolved in this order:

  1. The --file PATH option, when given.
  2. The MAQUINA_CREDENTIALS_FILE environment variable.
  3. credentials.yml.enc in the current working directory.

Ruby API

The same class is available through require "maquina_credentials".

credentials = Maquina::Credentials.new
credentials.read("anthropic_key")
credentials.read("database.password")  # dot-path traversal

# Writing replaces the whole file from a full hash:
Maquina::Credentials.write({
  anthropic_key: "sk-ant-...",
  database: {password: "prod-secret"}
})
  • Missing credential paths return an empty string (""), never nil.
  • All values are returned as strings.
  • A missing or empty MAQUINA_MASTER_KEY raises Maquina::Credentials::MasterKeyMissing (only when a credentials file actually exists).
  • A wrong key, tampered, truncated, or otherwise unreadable file raises Maquina::Credentials::DecryptionFailed.
  • An instance decrypts once and caches the result for the life of the object.

Security notes

  • Cipher is AES-256-GCM; the wire format is strict-base64 of IV (12 bytes) || ciphertext || GCM auth tag (16 bytes).
  • A fresh random IV is generated on every write.
  • Writes are atomic (temp file renamed into place) and the file is set to mode 0600.
  • YAML is parsed with safe_load(permitted_classes: []) on both read and write, so a tampered file cannot instantiate arbitrary Ruby objects.

Container workflow

# 1. Generate the master key once and store it as a secret.
mcr generate

# 2. Write credentials locally.
MAQUINA_MASTER_KEY=<key> printf "anthropic_key: sk-ant-...\n" | mcr write

# 3. Commit credentials.yml.enc into the image — the key never goes in.
docker build -t my-app .

# 4. Inject the key at runtime (or via orchestrator secrets).
docker run -e MAQUINA_MASTER_KEY=<key> my-app

Development

After checking out the repo, run bin/setup to install dependencies. Then run bundle exec rake to run the tests and Standard Ruby. Use bin/console for an interactive prompt with the gem preloaded.

License

The gem is available as open source under the terms of the MIT License.