Skip to content

Commit

Permalink
Age (#79)
Browse files Browse the repository at this point in the history
Allow Strongbox to use age https://github.com/FiloSottile/age primitives for encrypting files.

This allows users to use `.strongbox_recipient` files in the Git repository for encryption and `~/.strongbox_identity` to store identities for decryption.

age encryption has feature parity with SIV and a few nice extras:

- fix the known issue with file ordering when decrypting
- allow multiple recipients
- compatible with `age` outside of Git workflow
- offloading encryption, compression and decoration to an external (and a very good) library

age encryption is _in addition_ to the current SIV encryption and remains backward compatible.
  • Loading branch information
george-angel authored Jul 18, 2024
1 parent 9dd2d2d commit 7ebf08d
Show file tree
Hide file tree
Showing 15 changed files with 923 additions and 700 deletions.
2 changes: 0 additions & 2 deletions .dockerignore

This file was deleted.

3 changes: 0 additions & 3 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1 @@
.docs
docs/_index.md
docs/README.md
strongbox
6 changes: 3 additions & 3 deletions .goreleaser.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ builds:
- arm64
ignore:
- goos: darwin
goarch: '386'
goarch: "386"
- goos: freebsd
goarch: arm64

Expand All @@ -36,7 +36,7 @@ brews:
description: Encryption for git users
homepage: https://github.com/uw-labs/strongbox
license: LGPL-3.0
folder: Formula
tap:
directory: Formula
repository:
owner: uw-labs
name: homebrew-tap
4 changes: 2 additions & 2 deletions integration_tests/Dockerfile → Dockerfile
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
FROM golang:1.19-alpine
FROM golang:1.22-alpine

RUN apk --no-cache add git

ENV GOPATH=/go CGO_ENABLED=0
COPY . /go/src/github.com/uw-labs/strongbox
WORKDIR /go/src/github.com/uw-labs/strongbox

ENTRYPOINT ["/bin/sh", "/go/src/github.com/uw-labs/strongbox/integration_tests/run.sh"]
ENTRYPOINT ["/bin/sh", "/go/src/github.com/uw-labs/strongbox/run_tests"]
5 changes: 1 addition & 4 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,7 @@ IMAGE=strongbox-test
.DEFAULT_GOAL := test

build-test-image:
docker build -t $(IMAGE) -f integration_tests/Dockerfile .
docker build -t $(IMAGE) -f Dockerfile .

test: build-test-image
docker run --tmpfs /root:rw --rm $(IMAGE)

bench:
go test -bench=.
138 changes: 78 additions & 60 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
![Strongbox](strongbox-logo.png)

Encryption for git users.
Encryption for Git users.

Strongbox makes it easy to encrypt and decrypt files stored in git, with minimal
divergence from a typical git workflow. Once installed, strongbox enables
normal use of commands such as `git diff` etc. and all of the files that should
be encrypted in the repository remain decrypted on your working copy.
Strongbox makes it easy to encrypt and decrypt files stored in Git, with
minimal divergence from a typical Git workflow. Once installed, Strongbox
enables normal use of commands such as `git diff` etc. and all of the files
that should be encrypted in the repository remain decrypted on your working
copy.

It supports use of different keys per directory if wanted. It can cover as many
or as few files as you wish based on
Expand All @@ -18,26 +19,39 @@ You can obtain a binary from https://github.com/uw-labs/strongbox/releases
Alternatively, assuming you have a working [Go](https://golang.org) installation, you can
install via the following command:

```bash
go install github.com/uw-labs/[email protected]
```console
$ go install github.com/uw-labs/[email protected]
```

### Homebrew

If you're on macOS or Linux and have [Homebrew](https://brew.sh/) installed, getting Strongbox is as simple as running:
If you're on macOS or Linux and have [Homebrew](https://brew.sh/) installed,
getting Strongbox is as simple as running:

```
brew install uw-labs/tap/strongbox
```console
$ brew install uw-labs/tap/strongbox
```

## Usage

Strongbox supports [age](https://github.com/FiloSottile/age) and
[siv](https://pkg.go.dev/github.com/jacobsa/crypto/siv?utm_source=godoc)
encryption. Age is the recommended option.

| encryption | identity / keyring file | recipient / key file |
| ---------- | ----------------------- | -------------------- |
| age | .strongbox_identity | .strongbox_recipient |
| siv | .strongbox-keyring | .strongbox-keyid |

If both identity / key files are present in the same directory,
`.strongbox_identity` (age) will be preferred.

1. As a one time action, install the plugin by running `strongbox -git-config`.
This will edit global git config to enable strongbox filter and diff
This will edit global Git config to enable Strongbox filter and diff
configuration.

2. In each repository you want to use strongbox, create `.gitattributes` file
containing the patterns to be managed by strongbox.
2. In each repository you want to use Strongbox, create `.gitattributes` file
containing the patterns to be managed by Strongbox.

For example:

Expand All @@ -46,49 +60,36 @@ brew install uw-labs/tap/strongbox
```

3. Generate a key to use for the encryption, for example:
```console
strongbox -gen-identity my-key
```
strongbox -gen-key my-key
```
This will add a new key to your `.strongbox_keyring`. By default, the
keyring is created in the `$HOME` directory, but this location can be changed
by setting the `$STRONGBOX_HOME` environmental variable.

4. Include a `.strongbox-keyid` file in your repository containing public key
you want to use (typically by copying a public key from
`$HOME/.strongbox_keyring` ) This can be in the same directory as the
protected resource(s) or any parent directory. When searching for
`.strongbox-keyid` for a given resource, strongbox will recurse up the
directory structure until it finds the file. This allows using different
keys for different subdirectories within a repository.

5. If strongbox keyring file is stored on different location `-keyring` can be used.
ie `strongbox [-keyring <keyring_file_path>] -gen-key key-name`

6. Following commands can be used to manually decrypt file without gitOps
```
# decrypt using default keyring file `$HOME/.strongbox_keyring`
strongbox -decrypt -recursive <path>
# decrypt using `keyring_file_path`
strongbox -keyring <keyring_file_path> -decrypt -recursive <path>
This will generate a new [age](https://github.com/FiloSottile/age) keypair
and place it in `~/.strongbox_identity`. You can specify alternative
location using `-identity-file` flag or setting `$HOME` envvar.

4. Include `.strongbox_recipient` file in your repository
(https://github.com/FiloSottile/age?tab=readme-ov-file#recipient-files).
This can be in the same directory as the protected resource(s) or any parent
directory. When searching for `.strongbox_recipient` for a given resource,
Strongbox will recurse up the directory structure until it finds the file.
This allows using different keys for different subdirectories within a
repository.

5. If Strongbox identity file is stored in different location `-identity-file`
can be used. ie `strongbox [-identity-file <identity_file_path>]
-gen-identity key-name`

# decrypt using private key `<key>`
strongbox -key <key> -decrypt -recursive <path>
# decrypt single file with given key
strongbox -decrypt -key <key>
```
## Existing project

Strongbox uses [clean and smudge
filters](https://git-scm.com/book/en/v2/Customizing-Git-Git-Attributes#filters_a)
to encrypt and decrypt files.

If you are cloning a project that uses strongbox, you will need to place the
key into your keyring file prior to cloning (checkout). Otherwise that filter
will fail and not decrypt files on checkout.
If you are cloning a project that uses Strongbox, you will need to have
identity in your Strongbox identity file prior to cloning (checkout). Otherwise
that filter will fail and not decrypt files on checkout.

If you already have the project locally and added the keys, you can remove and
If you already have the project locally and added identity, you can remove and
checkout the files to force the filter:
```
rm <files> && git checkout -- <files>
Expand All @@ -98,47 +99,64 @@ rm <files> && git checkout -- <files>

Following a `git add`, you can verify the file is encrypted in the index:

```
git show :/path/to/file
```console
$ git show :/path/to/file
```

Verify a file is encrypted in the commit:

```
git show HEAD:/path/to/file
```console
$ git show HEAD:/path/to/file
```

What you should see is a Strongbox encrypted resource, and this is what would
be pushed to the remote.

Compare an entire branch (as it would appear on the remote) to master:

```
git diff-index -p master
```console
$ git diff-index -p master
```

## Key rotation

To rotate keys, update the `.strongbox-keyid` with the new key id, then `touch`
all files/directories covered by `.gitattributes`. All affected files should now
show up as "changed".
To rotate keys, update the `.strongbox_recipient` with the new value, then
`touch` all files/directories covered by `.gitattributes`. All affected files
should now show up as "modified".

## Security

Strongbox uses SIV-AES as defined in rfc5297 in order to achieve authenticated
deterministic encryption.
Strongbox uses [age](https://github.com/FiloSottile/age) and SIV-AES as defined
in rfc5297.

## Testing

Run integration tests:

```console
$ make test
```
make test

## SIV manual decryption
Following commands can be used to decrypt files outside of the Git flow:

```console
# decrypt using default keyring file `$HOME/.strongbox_keyring`
strongbox -decrypt -recursive <path>

# decrypt using `keyring_file_path`
strongbox -keyring <keyring_file_path> -decrypt -recursive <path>

# decrypt using private key `<key>`
strongbox -key <key> -decrypt -recursive <path>

# decrypt single file with given key
strongbox -decrypt -key <key>
```

## Known issues

### Clone file ordering
### Clone file ordering (SIV only)

Given a `.strongbox-keyid` in the root of the repository and an encrypted file
in the same directory,*and* alphabetically it comes before the key-id file.
Expand Down
Loading

0 comments on commit 7ebf08d

Please sign in to comment.