File::SOPS
Pure Perl implementation of Mozilla SOPS (Secrets OPerationS) encrypted file format.
Synopsis
use File::SOPS;
# Encrypt a data structure
my $encrypted = File::SOPS->encrypt(
data => {
database => {
password => 'secret123',
host => 'db.example.com',
},
},
recipients => ['age1ql3z7hjy54pw3hyww5ayyfg7zqgvc7w3j2elw8zmrj2kg5sfn9aqmcac8p'],
format => 'yaml', # or 'json'
);
# Decrypt
my $data = File::SOPS->decrypt(
encrypted => $encrypted,
identities => ['AGE-SECRET-KEY-1...'],
);
# File operations
File::SOPS->encrypt_file(
input => 'secrets.yaml',
output => 'secrets.enc.yaml',
recipients => ['age1...'],
);
File::SOPS->decrypt_file(
input => 'secrets.enc.yaml',
output => 'secrets.yaml',
identities => ['AGE-SECRET-KEY-1...'],
);
# Extract single value without decrypting entire file
my $password = File::SOPS->extract(
file => 'secrets.enc.yaml',
path => 'database.password',
identities => ['AGE-SECRET-KEY-1...'],
);
# Rotate data key (re-encrypt with new key)
File::SOPS->rotate(
file => 'secrets.enc.yaml',
identities => ['AGE-SECRET-KEY-1...'],
);
Description
SOPS encrypts values in structured files (YAML, JSON) while keeping keys readable. This enables:
- Git-friendly diffs - see which keys changed without decrypting
- Partial file inspection without full decryption
- Multiple encryption backends (currently age, with PGP/KMS planned)
- MAC verification to detect tampering
Encrypted File Format
database:
password: ENC[AES256_GCM,data:xyz==,iv:abc==,tag:def==,type:str]
host: ENC[AES256_GCM,data:xyz==,iv:abc==,tag:def==,type:str]
sops:
age:
- recipient: age1ql3z7hjy...
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
<encrypted data key>
-----END AGE ENCRYPTED FILE-----
lastmodified: "2025-01-10T12:00:00Z"
mac: ENC[AES256_GCM,data:...,iv:...,tag:...,type:str]
version: 3.9.4
Interoperability
This module is fully compatible with the reference Go implementation. Files encrypted with File::SOPS can be decrypted with the sops CLI and vice versa.
Tested with sops v3.9.4.
Installation
cpanm File::SOPS
Or manually:
perl Makefile.PL
make
make test
make install
Dependencies
- Crypt::Age - age encryption
- CryptX - AES-GCM encryption
- YAML::XS - YAML parsing
- JSON::MaybeXS - JSON parsing
- Moo - OO framework
Encryption Backends
Currently supported:
- age - Modern encryption using X25519 + ChaCha20-Poly1305
Planned:
- PGP
- AWS KMS
- GCP KMS
- Azure Key Vault
- HashiCorp Vault
How It Works
- Generate a random 256-bit data key
- Encrypt the data key for each recipient using age
- Encrypt each value with AES-256-GCM using the data key
- Compute MAC over all values for tamper detection
- Store encrypted data keys in
sopsmetadata section
See Also
- SOPS - Reference implementation
- Crypt::Age - Perl age encryption
- age - age encryption specification
Author
Torsten Raudssus torsten@raudssus.de
License
This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.