Skip to content

Latest commit

 

History

History
104 lines (79 loc) · 3.3 KB

hacking.md

File metadata and controls

104 lines (79 loc) · 3.3 KB

Hacking on gopass

Note: See CONTRIBUTING.md for an overview.

This document provides an overview on how to develop on gopass.

Setting up an isolated development environment

With GPG

gopass should fully respect GOPASS_HOMEDIR overriding all gopass internal paths. However it will still use your normal GPG keyring and configuration. To override this you will need to set GNUPGHOME as well and possibly generate a new keyring.

$ export GOPASS_DEBUG_LOG=/tmp/gp1.log
$ export GOPASS_HOMEDIR=/tmp/gp1
$ mkdir -p $GOPASS_HOMEDIR
$ export GNUPGHOME=$GOPASS_HOMEDIR/.gnupg
# Make sure that you're using the correct keyring.
$ gpg -K
gpg: directory '/tmp/gp1/.gnupg' created
gpg: keybox '/tmp/gp1/.gnupg/pubring.kbx' created
gpg: /tmp/gp1/.gnupg/trustdb.gpg: trustdb created
$ gpg --gen-key
$ go build && ./gopass setup --crypto gpg --storage gitfs

With age

Using age is recommended for development since it's easier to set up. Setting GOPASS_HOMEDIR should be sufficient to ensure an isolated environment.

$ export GOPASS_DEBUG_LOG=/tmp/gp1.log
$ export GOPASS_HOMEDIR=/tmp/gp1
$ mkdir -p $GOPASS_HOMEDIR
$ go build && ./gopass setup --crypto age --storage gitfs

Extending gopass

The main extension model are small binaries that use the gopass API package. This package provides a small and easy to use API that should work with any up to date gopass setup.

This API encapsulates the exact same implementation that the CLI uses in a more nicely packaged format that's easier to use.

Note: The API is operating directly on the password store. It does not involve network operations or connecting to a gopass instance.

The API does not support setting up a new password store (yet). Users will need have an existing password store or use gopass setup to create a new one. The API will attempt to load an existing configuration or use it's built-in defaults. Then it initializes an existing password store and provides a simple set of CRUD operations.

Our API has some examples on how to use the API. The gopass-hibp binary should provide a more complete example that can be used as a blueprint.

import (
 "context"
 "fmt"

 "github.com/gopasspw/gopass/pkg/gopass/api"
 "github.com/gopasspw/gopass/pkg/gopass/secrets"
)

 ctx := context.Background()

 gp, err := api.New(ctx)
 if err != nil {
  panic(err)
 }

 // Listing secrets by their names (path within the store).
 ls, err := gp.List(ctx)
 if err != nil {
  panic(err)
 }

 for _, s := range ls {
  fmt.Printf("Secret: %s", s)
 }

 // Writing secrets to a specific location (path) in the store.
 sec := secrets.New()
 sec.SetPassword("foobar")
 if err := gp.Set(ctx, "my/new/secret", sec); err != nil {
  panic(err)
 }

 // Reading secrets by their name and revision from within the store.
 sec, err = gp.Get(ctx, "my/new/secret", "latest")
 if err != nil {
  panic(err)
 }
 fmt.Printf("content of %s: %s\n", "my/new/secret", string(sec.Bytes()))

 // Removing a secret by their name.
 if err := gp.Remove(ctx, "my/new/secret"); err != nil {
  panic(err)
 }

 // Cleaning up (waiting for background processing to complete).
 if err := gp.Close(ctx); err != nil {
  panic(err)
 }