sopsenc

package
v0.11.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 7, 2026 License: Apache-2.0 Imports: 21 Imported by: 0

Documentation

Overview

Package sopsenc encrypts a repository's secret files for the age recipients of the matching creation rule of its .sops.yaml. It holds public keys only: there is no private key and no decryption code path anywhere in the package (sopsenc's tests assert this for the whole module). Secret values it generates exist only in the encrypted output; the package logs nothing.

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrNoRule is returned when no creation rule of the .sops.yaml matches a
	// secret file's path; such a file is never committed in plaintext.
	ErrNoRule = errors.New("no creation rule matches")
	// ErrNoRecipients is returned for a creation rule without age recipients;
	// age public keys are the only key type the package encrypts for.
	ErrNoRecipients = errors.New("creation rule has no age recipients")
)
View Source
var (
	// ErrDuplicatePath is returned when a fileset names one path twice.
	ErrDuplicatePath = errors.New("duplicate file path")
	// ErrGeneratedInPlainFile is returned when a file that is not a secret file
	// declares a generated value other than a key pair's public half: a secret
	// value only lives encrypted.
	ErrGeneratedInPlainFile = errors.New("generated values other than a key pair's public half are only allowed in secret files")
	// ErrValueFrozen is returned when a new secret file shares a generated
	// value with a secret file that already exists in the repository. The
	// existing value cannot be reproduced without decryption, so the caller
	// has to reference the existing Secret instead.
	ErrValueFrozen = errors.New("generated value exists in an encrypted file already in the repository")
)
View Source
var ErrInvalidGenerated = errors.New("invalid generated value declaration")

ErrInvalidGenerated is returned for a Generated declaration that is incomplete, inconsistent across files, or whose placeholder is absent from the file it is declared on.

Functions

func IsSecretFile

func IsSecretFile(p string) bool

IsSecretFile reports whether a path names a secret file by the file-naming convention: a base name containing "secret" or "credential". It is the naming contract for callers that render secret files, not the encryption decision: which files Encrypt encrypts follows the repository's .sops.yaml (Encryptor.IsSecretFile), whose path_regex rules match paths — a file under a secrets/ directory is a secret file whatever its name.

Types

type Config

type Config struct {
	// contains filtered or unexported fields
}

Config is a repository's parsed .sops.yaml.

func ParseConfig

func ParseConfig(sopsYAML []byte) (Config, error)

ParseConfig parses a .sops.yaml. Every rule's path_regex must compile and every rule must name at least one valid age recipient.

func (Config) IsSecretFile added in v0.6.0

func (c Config) IsSecretFile(p string) bool

IsSecretFile reports whether the repository's .sops.yaml makes the repository-relative path a secret file: a creation rule's path_regex matches it, whatever its name, or its name follows the secret-file convention (the package-level IsSecretFile). Such a file is encrypted for its rule's recipients or refused with ErrNoRule; it is never written in plaintext. A rule without path_regex names recipients for every secret file and makes no path a secret by itself. The kustomize entry-point files are never secret files.

func (Config) Rule

func (c Config) Rule(path string) (Rule, error)

Rule returns the first creation rule whose path_regex matches the repository-relative path.

type Encoding added in v0.8.0

type Encoding string

Encoding is how a placeholder receives its value: as it is (the zero value), or encoded for a consumer that decodes the leaf.

const EncodingBase64 Encoding = "base64"

EncodingBase64 is the value's standard base64 with padding: for a Secret key written under data:, or a chart that copies the value under data: as it is. It applies to a Base64 or Alphanumeric value; a key pair's halves are quoted YAML scalars and take no encoding.

type Encryptor

type Encryptor struct {
	// contains filtered or unexported fields
}

Encryptor encrypts secret files for one repository's .sops.yaml.

func New

func New(sopsYAML []byte) (*Encryptor, error)

New parses the repository's .sops.yaml.

func (*Encryptor) Encrypt

func (e *Encryptor) Encrypt(files []File, exists func(path string) bool) (map[string][]byte, error)

Encrypt returns the fileset ready to commit, keyed by repository-relative path. Files the repository's .sops.yaml does not make secret files (IsSecretFile) pass through in plaintext, a key pair's public half filled in where one is declared. A secret file that exists in the repository (exists reports its path) is left as it is and absent from the result: it is never re-generated. Every other secret file has its generated values filled in — one value or key pair per name across all files — and is encrypted for the recipients of its creation rule; a secret file no rule covers is refused with ErrNoRule.

func (*Encryptor) IsSecretFile added in v0.6.0

func (e *Encryptor) IsSecretFile(path string) bool

IsSecretFile reports whether Encrypt treats the repository-relative path as a secret file, by the repository's .sops.yaml (Config.IsSecretFile).

type File

type File struct {
	// Path is repository-relative, the path .sops.yaml's path_regex sees.
	Path    string
	Content []byte
	// Generated declares the placeholders in Content that receive generated
	// values. A file that is not a secret file may declare a key pair's
	// public half only.
	Generated []Generated
}

File is one rendered file of a repository's fileset.

type Generated

type Generated struct {
	Name        string
	Placeholder string
	Kind        Kind
	// Length is the size of a Base64 or Alphanumeric value; a key pair has none.
	Length int
	// Half is the half of a KeyPairES256 the placeholder receives; a Base64 or
	// Alphanumeric value has none.
	Half Half
	// Encoding is how the placeholder receives the value; empty is the value
	// as generated.
	Encoding Encoding
}

Generated declares a secret value the package generates at commit time and writes in place of Placeholder in the declaring file. The same Name in two files is one value; its Kind and Length must agree wherever it is declared. A key pair's declarations name the Half each placeholder receives; its private half exists only in the encrypted output. Each declaration names the Encoding its placeholder receives: that is how one value lands as it is where it is read and base64 where the consumer decodes it.

type Half added in v0.7.0

type Half string

Half is the half of a key pair a placeholder receives.

const (
	// Private is the private key; only a secret file may receive it.
	Private Half = "private"
	// Public is the public key; a plain file may receive it too.
	Public Half = "public"
)

type Kind

type Kind string

Kind is the shape of a generated secret value.

const (
	// Base64 is Length random bytes in standard base64 with padding.
	Base64 Kind = "base64"
	// Alphanumeric is Length characters drawn from [A-Za-z0-9].
	Alphanumeric Kind = "alphanumeric"
	// KeyPairES256 is an ECDSA P-256 key pair — the pair behind the JWS
	// algorithm ES256 — drawn once per name; each declaration names the Half
	// its placeholder receives. The private half is a PKCS #8 PEM, the public
	// half a SubjectPublicKeyInfo PEM: what `openssl pkey` writes and jose's
	// importPKCS8/importSPKI read. A half replaces its placeholder as a
	// double-quoted YAML scalar whose line breaks are \n escapes, so the
	// placeholder stands as the whole, unquoted value of a key and the PEM
	// survives nesting inside a values document. Length is not used.
	KeyPairES256 Kind = "keypair-es256"
)

type Rule

type Rule struct {
	PathRegex *regexp.Regexp
	// Recipients are age public keys.
	Recipients        []string
	EncryptedRegex    string
	UnencryptedRegex  string
	EncryptedSuffix   string
	UnencryptedSuffix string
}

Rule is one creation rule: the paths it covers and the recipients it encrypts for. Files match the first rule in .sops.yaml order; a rule without path_regex matches every path.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL