Documentation
¶
Overview ¶
Package secret holds the key that encrypts private response bodies and the encryption itself (AES-256-GCM). The key comes from the environment, the macOS Keychain or 1Password, or, for a project that keeps everything in its own folder (baselines: local), from a key file there that git ignores and only its owner can read.
Index ¶
- Constants
- Variables
- func Create(project string) error
- func CreateFile(path string) error
- func Environ() []string
- func HideEnv(name string)
- func WriteFile(path string, k Key) error
- type Key
- func (k Key) Open(sealed, aad []byte) ([]byte, error)
- func (k Key) OpenInPlace(sealed, aad []byte) ([]byte, error)
- func (k Key) Ref(plaintext []byte) string
- func (k Key) RefHash() hash.Hash
- func (k Key) Seal(plaintext, aad []byte) ([]byte, error)
- func (k Key) SealInPlace(plaintext, aad []byte) (header, ciphertext []byte, err error)
- type Source
Constants ¶
const EnvKey = "DRIFTGATE_KEY"
EnvKey is the environment variable that may hold the base64 key.
const KeySize = 32
KeySize is the length of an AES-256 key.
Variables ¶
var ErrNoKey = errors.New("no encryption key: set " + EnvKey + ", run 'driftgate key create', or configure key.op")
ErrNoKey means no key source produced a key.
Functions ¶
func Create ¶
Create generates a key and stores it in the macOS Keychain. The key is passed to `security` on stdin, never as an argument visible in the process list.
func CreateFile ¶
CreateFile generates a key and writes it to path (base64, open to its owner only). An existing file is never replaced: private bodies encrypted with its key would become unreadable.
func Environ ¶
func Environ() []string
Environ is the environment of a command DriftGate runs (hooks, adapters, token commands, git): its own, without the variables that hold a key. The commands come from the repository, which a pull request may change.
A variable is left out by its name (DRIFTGATE_KEY, key.env) or by its value: the project key as loaded, or the key a hidden variable holds, in any of keyForms, so a copy of the key under another name (a CI secret exported twice) is left out too. This is defence in depth, not a boundary: a key in another form (in a file, inside a longer value) or a command that reads the key from where DriftGate got it (1Password, the Keychain) is not stopped.
Types ¶
type Key ¶
type Key []byte
Key is an AES-256 key.
func Load ¶
Load finds the key for a project. file is the key file of a project that keeps its key in its own folder; when it is set it takes the place of the Keychain.
func (Key) OpenInPlace ¶
OpenInPlace is Open that decrypts into sealed's own storage, so a body is held once: sealed is overwritten (and holds nothing usable after an error), and the plaintext returned shares its memory.
func (Key) Ref ¶
Ref names a private body without revealing it: the HMAC-SHA256 of the plaintext under a key derived from k. Equal bodies get equal names under one key, but a guess of a short body cannot be checked against the name without the key, as it could against a plain SHA-256.
func (Key) RefHash ¶
RefHash is Ref for content read in parts: its sum, in hex, is the ref of what was written to it.
func (Key) SealInPlace ¶
SealInPlace is Seal that encrypts into plaintext's own storage, so a body is held once: plaintext is overwritten and must not be used afterwards. The header (format mark and nonce) comes back apart from the ciphertext; written one after the other they are what Seal returns. Without room for the tag in plaintext's capacity the ciphertext gets storage of its own.