* docs(adr): resolve the A-13 collision, zero-pad numbers and add an index
Two records carried the number A-13:
docs/adr/A-13-expired-gpg-key-handling.md
docs/adr/A-13-screenshot-build-tag.md
An ADR number is a stable identifier, so a duplicate makes every citation
ambiguous. A-13-expired-gpg-key-handling.md keeps the number: it is cited
from docs/commands/recipients.md, docs/usecases/team-workflows.md and
docs/adr/A-14-team-workflows.md. The screenshot record has no inbound
citations and is renumbered to A-15.
Zero-pad A-3 through A-9 to A-03 through A-09 so the directory sorts
correctly now that the set has passed ten entries. None of these has an
inbound citation from another document; the single reference in
internal/backend/storage/fs/rcs.go is updated in this commit.
Add docs/adr/README.md as the index, recording the naming rules, the status
and authoring date of every record, and three facts that are otherwise only
discoverable from git history:
- A-01 and A-02 are cited from the CHANGELOG unreleased section but no file
was ever written for either; the numbers stay reserved.
- The A-13 collision and which record was renumbered.
- SECURITY_AUDIT_REPORT.md and CODE_QUALITY_REPORT.md, cited as the Source
of A-03 through A-10, were removed in 77894053 and are not in the tree.
No record content is changed apart from the H1 lines, which must match the
file names.
Signed-off-by: Pavel Lavrukhin <46395539+dantte-lp@users.noreply.github.com>
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* docs: add docs/conventions.md and adopt Conventional Commits
CONTRIBUTING.md required a bracketed [TAG] prefix on every commit subject.
That has not matched practice for some time: of the 344 commit subjects
since 2025-01-01, 225 are Conventional Commits and 67 use a [TAG]. The
CHANGELOG unreleased section uses a third set including [SECURITY] and
[PKG-BREAK], neither of which CONTRIBUTING.md lists.
Replace the [TAG] rule with Conventional Commits and add
docs/conventions.md as the single normative reference for:
- commit types (a closed list) and the scopes derived from the package
layout, including the five values that appear as types in the history but
are scopes: otp, age, bug, fscopy, openbsd;
- the distinction between a CLI break, which uses "!" and a
BREAKING CHANGE: footer and forces a major release, and a break confined
to pkg/gopass, which uses a PKG-BREAK: footer and does not (ADR A-12);
- Semantic Versioning, and which surfaces it does and does not cover;
- branch and tag names, including the release/ and prep/ prefixes owned by
the release automation;
- file naming for ADRs, documentation and Go sources.
The Developer Certificate of Origin requirement is unchanged. Conventional
Commits governs the subject line and the DCO adds a trailer, so the two are
independent.
Also correct the API Stability section of ARCHITECTURE.md, which still
described pkg/gopass/doc.go as carrying "an explicit instability warning"
and instructed consumers to "treat any pkg/ type or function change as
potentially breaking". Both statements predate ADR A-12: doc.go now
declares the package best-effort stable and permits additive changes in any
release. The section also referred to issue #3414 as an open decision; that
decision is recorded in A-12 with status accepted.
Extend the folder list in AGENTS.md with the five pkg/ directories it does
not mention (otp, passkey, pinentry/cli, protect, qrcon), using each
package's own doc comment as the description.
Signed-off-by: Pavel Lavrukhin <46395539+dantte-lp@users.noreply.github.com>
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
8.5 KiB
Project Overview
gopass is a command line application that allows users to managed their passwords and other secrets inside encrypted files. Those files are usually encrypted using gpg (but other backends like age do exist). The files are usually managed using git (but other VCS backends exist as well). The CLI is primarily intended for human users.
Several integration exist, these are stand alone projects that use the exposed gopass API to interact with an existing password store.
gopass supports multiple password stores. It requires at least one root store but any number of additional stores can be mounted, just like filesystems on Linux, inside the root store. Each store can use a different encryption method and VCS.
The primary use case of using different password stores is to encrypt and share the content with a different set of recipients.
The project is specifically targeting users on all major platform, i.e. Linux, Unix, MacOS and Windows.
Folder Structure
/docs: Contains human readable documentation for the project./helpers: Contains tools used to maintain the project. Users usually don't use those, these are mainly for developers and maintainers of the project. Do not touch this directory unless instructed to do so./internal: Contains most of the implementation of the project. It is visibility restricted so other projects can not depend on it and we can be very liberal with breaking changes./pkg: Contains the public API (inside/pkg/gopass) used by our integrations and other projects as well as necessary support packages to make using the API feasible./tests: Contains only integration tests, i.e. those mock a real GPG-based gopass installation. They are quite slow but provide kind of a regression testing. Remember to add or adjust those when adding major new features./internal/action: Contains the different CLI subcommands. Usually one file per top-level subcommand (e.g. the implementation forgopass lsis in/internal/action/list.go) with an accompanying_test.gofile that contains the unit tests. All commands need to be registered in/internal/action/commands.go./internal/audit: Contains the audit code that checks password stores for weak passwords or related issues./internal/backend: Contains the different backend implementations for both encryption as well as version controlled storage. Storage implementations need to register themselves in/internal/backend.StorageRegistrywhile encryption backends need to register in/internal/backend.CryptoRegistry./internal/backend/crypto/age: Contains theageencryption backend. It is a pure-Go implementation. Refer to the docs as well./internal/backend/crypto/gpg/cli: Contains thegpgencryption backend. It mostly uses thegpgbinary to support the different configurations (e.g. smart cards) which wouldn't be possible with existing pure-Go implementation. Refer to docs as well./internal/backend/crypto/plain: Contains the plaintext backend (no encryption). This should only be used for testing. Users should never use this./internal/backend/storage/fossilfs: Contains an experimental storage backend using the Fossil SCM. It might be removed in the future./internal/backend/storage/fs: Contains a storage backend without SCM integration, i.e. it simply writes to files on disk without versioning support. Should usually only be used for tests or if users have some kind of transparent versioning system underneath./internal/backend/storage/gitfs: Contains the primary storage backend that is usinggitto manage files./internal/config: Contains our custom config handling. It is based on the git configuration file format as implemented by our gitconfig package. When reading config settings prefer to usingconfig.Bool(ctx, key),config.String(ctx, key)orconfig.Int(ctx, key). Use the low-level methods only when those are not sufficient. Avoid touching thelegacypackage underneath unless asked to./internal/out: Contains our output helpers. Prefer those over Go standard lib packages (like fmt) for consistency./internal/store: Contains the core of the password store implementation (utilizing the configured backends)./internal/store/root: Contains the root store. This always exist once in a gopass process. It delegates most operations to one or more leaf stores./internal/store/leaf: Contains the leaf store. There must be at least one initialized leaf store per gopass instance. But there can be as many as necessary./pkg/appdir: Contains a facility for providing system-dependentt paths for application resources, like config or cache directories. It does honor theGOPASS_HOMEDIRvariable. This is very useful for testing since a gopass instance running with this variable set to a temporary location will not interfere with the actual production instance a user might be using./pkg/clipboard: Contains methods to interact with clipboards on all major operating systems. It is using our clipboard package. It also supports clearing the clipboard after a given interval./pkg/ctxutil: Provides the necessary plumbling to interact with config values stored in the context. Avoid adding new context keys if possible and prefer config values. But if adding context keys is necessary they should only be defined in this file./pkg/debug: Contains a debug package with different verbosity levels. Use it to output debug information to a debug log./pkg/fsutil: Contains various helpers for interacting with the filesystem, e.g. checking for presence of files or directories. Prefer those over implementing these checks from scratch./pkg/gopass: Contains the public gopass API to interact with existing password stores. Theapisub package contains the actual API and thesecretssub package the different secret types we support./pkg/otp: Contains functions to handle OTP secrets. It parses OTP secrets from various formats and generates QR codes for them./pkg/passkey: Implements support for WebAuthn credentials for authentication./pkg/pinentry/cli: Contains a pinentry client that uses the terminal for input and output. It is a drop-in replacement for thepinentryprogram, used to ask for a passphrase or PIN. Note that/pkg/pinentryitself holds no Go files;cliis the only package under it./pkg/protect: Provides an interface to thepledgesyscall, used to limit the system calls the process can make.pledgeexists only on OpenBSD; this package is a no-op everywhere else./pkg/pwgen: Contains a pure-Go implementation of thepwgenutility./pkg/qrcon: Implements a QR code ANSI printer for displaying QR codes on the console./pkg/set: Contains a generic set type./pkg/tempfile: Contains utility functions for creating and dealing with temp files. It attempts to be more secure than the normal temp file functions from the stdlib. Prefer those over the stdlib./pkg/termio: Contains functions for interacting with the user of the terminal.
Conventions
Commit messages, versioning, branch and tag names, and file naming are specified in docs/conventions.md. Observe these three rules in particular:
- Use only the listed commit types:
feat fix security perf refactor revert deps docs test build ci chore. The list is closed.otp,age,fscopy,bugandopenbsdappear as types in the history; they are scopes and must be written as such. - Use
!and aBREAKING CHANGE:footer only for a break in the CLI. Mark a break confined to thepkg/gopassGo module with aPKG-BREAK:footer and no!. The first forces a major release; the second does not. - Write the pull request title as a valid Conventional Commit. Pull requests are squash-merged, so the pull request title is the string that reaches
CHANGELOG.md, not the individual commit subjects.
Libraries and Frameworks
- Avoid introducing new external dependencies unless absolutely necessary.
- If a new dependency is required, please state the reason.
- The project is licensed under the terms of the MIT license and we can only add compatible licenses. See .license-lint.yml for a list of compatible licenses.
- We must avoid introducing CGo dependencies since this make cross-compiling infeasible.
Testing instructions
- Always run
make testandmake codequalitybefore submitting. - Run
make fmtto properly format the code. Run this beforemake codequality. - Before mailing a PR run
make test-integration