Skip to content

dhoelle/redactr

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

49 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

redactr

Build Status Go Report Card License: MIT

redactr replaces secrets with Redacted Secrets.

With the right privileges, redactr can replace Redacted Secrets with secrets.

Table of Contents

Install

Binary

Binaries are available on the releases page

Brew (Mac OS)

brew tap dhoelle/tap
brew install dhoelle/tap/redactr

Build from source

Requires Go >1.11

go get github.com/dhoelle/redactr/cmd/redactr

Example (CLI)

First, set some environment variables, which redactr will use to redact and unredact secrets:

export AES_KEY="xuY6/V0ZE29RtPD3TNWga/EkdU3XYsPtBIk8U4nzZyc="
export VAULT_ADDR=http://localhost:8200
export VAULT_TOKEN=my_token

Redact secrets

redactr redact <<EOF
My email password is ~~redact:hunter2~~
My database password is ~~redact-vault:path/to/kv/secret#my_key#swordfish~~
EOF
# output:
# My email password is ~~redacted-aes:DYeT3hCH1unjeWl9whMhjn/ILcM3r24XaX7xgWO8sOJkvCs=~~
# My database password is ~~redacted-vault:path/to/kv/secret#my_key~

Unredact secrets

redactr unredact <<EOF
My email password is ~~redacted-aes:DYeT3hCH1unjeWl9whMhjn/ILcM3r24XaX7xgWO8sOJkvCs=~~
My database password is ~~redacted-vault:path/to/kv/secret#my_key~~
EOF
# output:
# My email password is hunter2
# My database password is swordfish

By default secrets are unredacted without the original secret wrapping. You can add it back with the -w/--wrap-tokens flag:

redactr unredact -w <<EOF
My email password is ~~redacted-aes:DYeT3hCH1unjeWl9whMhjn/ILcM3r24XaX7xgWO8sOJkvCs=~~
My database password is ~~redacted-vault:path/to/kv/secret#my_key~~
EOF
# output:
# My email password is ~~redact:hunter2~~
# My database password is ~~redact-vault:path/to/kv/secret#my_key#swordfish~~

Execute commands

redactr exec executes commands with redacted secrets in its environment

PASSWORD="~~redacted-aes:DYeT3hCH1unjeWl9whMhjn/ILcM3r24XaX7xgWO8sOJkvCs=~~" \
redactr exec echo 'my password is $PASSWORD'
# output: my password is hunter2

Re-evaluating the environment

Some redactr secrets are dynamic. For example, passwords in a vault instance can change over time.

redactr exec can be configured to periodically unredact the secrets that a command uses and, if they have changed, either stop or restart the command.

The following example creates a local vault instance and changes a password every second, then runs a command with redactr exec which re-runs on each change:

# Start a local vault instance
docker run -d --cap-add=IPC_LOCK -e 'VAULT_DEV_ROOT_TOKEN_ID=myroot' -p 8222:8200 vault
sleep 1

# Start a background job which changes a secret every second for 20 seconds
func changesecrets() {
    for i in {1..10}
    do
        VAULT_ADDR=http://0.0.0.0:8222 VAULT_TOKEN=myroot vault kv put secret/db_password value=hunter2
        sleep 1
        VAULT_ADDR=http://0.0.0.0:8222 VAULT_TOKEN=myroot vault kv put secret/db_password value=swordfish
        sleep 1
    done
}
changesecrets &>/dev/null &
sleep 1

# use `redactr exec` to print the secret and block.
# Each time the secret changes, the command will
# restart and the new secret will be printed.
VAULT_ADDR=http://localhost:8222 \
VAULT_TOKEN=myroot \
SECRET_KEY=~~redacted-vault:secret/data/db_password#value~~ \
redactr exec \
    -r 1000ms
    /bin/bash -c 'echo "$(date): secret key: $SECRET_KEY"; sleep 3'

# example output:
# Tue Apr 30 18:42:24 PDT 2019: secret key: swordfish
# Tue Apr 30 18:42:25 PDT 2019: secret key: hunter2
# Tue Apr 30 18:42:26 PDT 2019: secret key: swordfish
# ...

Example (Go Library)

package main

import (
	"fmt"
	"log"

	"github.com/dhoelle/redactr"
)

func main() {
	c, _ := redactr.New(
		redactr.AESKey("xuY6/V0ZE29RtPD3TNWga/EkdU3XYsPtBIk8U4nzZyc="),
	)

	plaintext := "foo ~~redact:hunter2~~ baz"
    redacted, _ := c.RedactTokens(plaintext)
    fmt.Println(redacted) // "foo secret-encrypted:DYeT3hCH1unjeWl9whMhjn/ILcM3r24XaX7xgWO8sOJkvCs=~~-encrypted baz"

    unredacted, _ := c.UnredactTokens(redacted)
    fmt.Println(redacted) // "foo hunter2 baz"

    unredacted, _ = c.UnredactTokens(redacted, redactr.WrapTokens)
    fmt.Println(redacted) // "foo ~~redact:hunter2~~ baz"
}

Example (Docker)

A docker image is available: https://cloud.docker.com/repository/docker/dhoelle/redactr

$ docker run \
    -e AES_KEY="xuY6/V0ZE29RtPD3TNWga/EkdU3XYsPtBIk8U4nzZyc=" \
    dhoelle/redactr \
    unredact "~~redacted-aes:DYeT3hCH1unjeWl9whMhjn/ILcM3r24XaX7xgWO8sOJkvCs=~~"

# output:
# hunter2

Secret types

type unredacted form redacted form
local secret redact:* redacted-aes:*
vault KV secret redact-vault:path/to/secret#key#value redacted-vault:path/to/secret#key

Encrypted secrets (AES-256-GCM)

Secrets can be redacted via 256-bit AES-GCM encryption.

$ redactr key
xuY6/V0ZE29RtPD3TNWga/EkdU3XYsPtBIk8U4nzZyc=

$ export AES_KEY="xuY6/V0ZE29RtPD3TNWga/EkdU3XYsPtBIk8U4nzZyc="

$ redactr redact "~~redact:hunter2~~"
~~redacted-aes:JOf+CmAfgyCSbesz6zstfUx7gHIuJ/JMeyyf8UqCGvkxjkc=~~

$ redactr unredact "~~redacted-aes:JOf+CmAfgyCSbesz6zstfUx7gHIuJ/JMeyyf8UqCGvkxjkc=~~"
hunter2

# Use the -w (--wrap) flag to return a reversible wrapped secret
$ redactr unredact -w "~~redacted-aes:JOf+CmAfgyCSbesz6zstfUx7gHIuJ/JMeyyf8UqCGvkxjkc=~~"
~~redact:hunter2~~

Hashicorp Vault

Secrets may be stored in a Hashicorp Vault instance.

The vault adapter uses the vault CLI's standard environment variables (see: https://www.vaultproject.io/docs/commands/#environment-variables)

Assuming vault has been appropriately configured, it can be used like:

$ redactr redact "~~redact-vault:/dev#my_password#hunter2~~"
vault~~/dev#my_password

$ redactr unredact "~~redacted-vault:/dev#my_password~~"
hunter2

# Use the -w (--wrap) flag to return a reversible wrapped secret
$ redactr unredact -w "~~redacted-vault:/dev#my_password~~"
~~redact-vault:/dev#my_password#hunter2~~

About

Keep obscured secrets alongside plaintext

Resources

License

Stars

Watchers

Forks

Packages

No packages published