NAME

File::SOPS::Metadata - SOPS metadata section handling

VERSION

version 0.001

SYNOPSIS

use File::SOPS::Metadata;

# Create new metadata
my $meta = File::SOPS::Metadata->new(
    unencrypted_suffix => '_unencrypted',
);

# Add age recipient
$meta->add_age_recipient(
    recipient => 'age1ql3z7hjy54pw3hyww5ayyfg7zqgvc7w3j2elw8zmrj2kg5sfn9aqmcac8p',
    enc       => '-----BEGIN AGE ENCRYPTED FILE-----...',
);

# Update timestamp
$meta->update_lastmodified;

# Set MAC
$meta->mac($mac_string);

# Convert to hash for serialization
my $hash = $meta->to_hash;

# Parse from existing hash
my $meta = File::SOPS::Metadata->from_hash($sops_section);

DESCRIPTION

File::SOPS::Metadata manages the sops metadata section of encrypted files. This section contains:

  • Encrypted data keys for each recipient/backend

  • MAC for tamper detection

  • Timestamp of last modification

  • Rules for which keys should be encrypted

  • SOPS version information

age

ArrayRef of age-encrypted data keys. Each entry is a HashRef with:

{
    recipient => 'age1...',
    enc       => '-----BEGIN AGE ENCRYPTED FILE-----...'
}

Defaults to [].

pgp

ArrayRef of PGP-encrypted data keys. Not yet implemented. Defaults to [].

kms

ArrayRef of AWS KMS-encrypted data keys. Not yet implemented. Defaults to [].

gcp_kms

ArrayRef of Google Cloud KMS-encrypted data keys. Not yet implemented. Defaults to [].

azure_kv

ArrayRef of Azure Key Vault-encrypted data keys. Not yet implemented. Defaults to [].

hc_vault

ArrayRef of HashiCorp Vault-encrypted data keys. Not yet implemented. Defaults to [].

mac

Message Authentication Code over the entire encrypted data structure.

Stored as an encrypted value string: ENC[AES256_GCM,data:...,iv:...,tag:...,type:str]

lastmodified

ISO 8601 timestamp of last modification. Example: 2025-01-10T12:00:00Z

version

SOPS version string. Defaults to 3.7.3 for compatibility with the Go implementation.

unencrypted_suffix

Keys ending with this suffix are not encrypted (but are included in MAC).

Defaults to _unencrypted.

Example: api_key_unencrypted would not be encrypted.

encrypted_suffix

If set, only keys ending with this suffix are encrypted.

Defaults to undef (all keys are encrypted unless they match unencrypted rules).

unencrypted_regex

Regular expression for keys that should not be encrypted.

Defaults to undef.

encrypted_regex

Regular expression for keys that should be encrypted.

Defaults to undef.

from_hash

my $meta = File::SOPS::Metadata->from_hash($hash);

Class method to create a Metadata object from a HashRef.

Typically used when parsing the sops section from a YAML/JSON file.

Returns undef if the input is not a HashRef.

to_hash

my $hash = $meta->to_hash;

Converts the Metadata object to a HashRef for serialization.

This HashRef is written to the sops section of the encrypted file.

update_lastmodified

$meta->update_lastmodified;

Sets lastmodified to the current time in ISO 8601 format (UTC).

Returns $self for chaining.

add_age_recipient

$meta->add_age_recipient(
    recipient => 'age1ql3z7hjy54pw3hyww5ayyfg7zqgvc7w3j2elw8zmrj2kg5sfn9aqmcac8p',
    enc       => '-----BEGIN AGE ENCRYPTED FILE-----...',
);

Adds an age recipient with their encrypted data key.

The enc parameter should be the PEM-armored age-encrypted data key.

Returns $self for chaining.

get_age_encrypted_keys

my @keys = $meta->get_age_encrypted_keys;

Returns a list of age-encrypted data key entries (HashRefs).

Each entry has recipient and enc fields.

should_encrypt_key

if ($meta->should_encrypt_key('api_key')) {
    # Encrypt this key
}

Determines if a hash key should be encrypted based on suffix/regex rules.

Rules are applied in this order:

1. If unencrypted_suffix is set and key ends with it, return false
2. If encrypted_suffix is set, return true if key ends with it, else false
3. If unencrypted_regex is set and key matches, return false
4. If encrypted_regex is set and key matches, return true, else false
5. Default: return true (encrypt everything)

Returns true if the key should be encrypted, false otherwise.

SEE ALSO

SUPPORT

IRC

You can reach Getty on irc.perl.org for questions and support.

CONTRIBUTING

Contributions are welcome! Please fork the repository and submit a pull request.

AUTHOR

Torsten Raudssus <torsten@raudssus.de>

COPYRIGHT AND LICENSE

This software is copyright (c) 2026 by Torsten Raudssus.

This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.