* feat: Add cryptfs storage backend for filename encryption
This commit introduces a new storage backend called `cryptfs`. This backend encrypts the filenames of secrets to enhance privacy while maintaining compatibility with existing VCS backends like Git.
Key features:
- For each secret, a cryptographically secure hash (SHA-256) of its name is generated and used as the filename for the underlying storage.
- A mapping from the original secret name to the hashed filename is maintained in an encrypted file (`.gopass-mapping.age`) within the repository.
- The mapping file is encrypted using the `age` encryption backend, with recipients read from the store's `.age-recipients` file.
- The `cryptfs` backend is implemented as a wrapper around any existing storage backend (e.g., `gitfs`, `fs`), which can be configured by the user.
- The backend is registered with gopass and can be enabled by setting `storage: cryptfs` in the store's configuration.
This implementation addresses issue #2634.
* [fix] Fix lint errors
Signed-off-by: Dominik Schulz <dominik.schulz@gauner.org>
* [chore] Fix the remaining tests and add some docs.
Signed-off-by: Dominik Schulz <dominik.schulz@gauner.org>
---------
Signed-off-by: Dominik Schulz <dominik.schulz@gauner.org>
Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
Co-authored-by: Dominik Schulz <dominik.schulz@gauner.org>
* This change introduces an agent for the age backend to cache passphrases for age identities.
The agent is a long-running process that listens on a Unix domain socket. Gopass communicates with the agent to request decryption of secrets. The agent caches the passphrases for the identities and performs the decryption, so the passphrases never leave the agent process. This addresses the security concerns with the initial implementation.
The agent can be controlled with the following commands:
- `gopass age agent`: starts the agent in the foreground.
- `gopass age lock`: locks the agent, clearing all cached passphrases.
The age backend will automatically start the agent if it's not already running and the `age.agent-enabled` configuration option is set to `true` (the default).
This change includes:
- The implementation of the age agent in `internal/backend/crypto/age/agent/`.
- Modifications to the age backend to communicate with the agent.
- A new configuration option `age.agent-enabled`.
- Unit tests for the agent.
- Updated documentation for the age backend.
The integration test for this feature (`TestAgeAgent`) is currently failing. The issue is that the test environment is non-interactive, and the code path for initializing a new age store requires a password for the identity keyring, which triggers a `pinentry` call that fails without a TTY. I have tried several approaches to work around this, including setting the `GOPASS_PASSWORD` environment variable and providing a custom pinentry script, but none have been successful so far. The core implementation of the agent is believed to be correct, but the integration test needs further work to run in a non-interactive environment.
* This change introduces an agent for the age backend to cache passphrases for age identities.
The agent is a long-running process that listens on a Unix domain socket. Gopass communicates with the agent to request decryption of secrets. The agent caches the passphrases for the identities and performs the decryption, so the passphrases never leave the agent process. This addresses the security concerns with the initial implementation.
The agent can be controlled with the following commands:
- `gopass age agent`: starts the agent in the foreground.
- `gopass age lock`: locks the agent, clearing all cached passphrases.
The age backend will automatically start the agent if it's not already running and the `age.agent-enabled` configuration option is set to `true` (the default).
This change includes:
- The implementation of the age agent in `internal/backend/crypto/age/agent/`.
- Modifications to the age backend to communicate with the agent.
- A new configuration option `age.agent-enabled`.
- Unit tests for the agent.
- Updated documentation for the age backend.
* This change introduces an agent for the age backend to cache passphrases for age identities.
The agent is a long-running process that listens on a Unix domain socket. Gopass communicates with the agent to request decryption of secrets. The agent caches the passphrases for the identities and performs the decryption, so the passphrases never leave the agent process. This addresses the security concerns with the initial implementation.
The agent can be controlled with the following commands:
- `gopass age agent`: starts the agent in the foreground.
- `gopass age lock`: locks the agent, clearing all cached passphrases.
The age backend will automatically start the agent if it's not already running and the `age.agent-enabled` configuration option is set to `true` (the default).
This change includes:
- The implementation of the age agent in `internal/backend/crypto/age/agent/`.
- Modifications to the age backend to communicate with the agent.
- A new configuration option `age.agent-enabled`.
- Unit tests for the agent.
- Updated documentation for the age backend.
* This change introduces an agent for the age backend to cache passphrases for age identities.
The agent is a long-running process that listens on a Unix domain socket. Gopass communicates with the agent to request decryption of secrets. The agent caches the passphrases for the identities and performs the decryption, so the passphrases never leave the agent process. This addresses the security concerns with the initial implementation.
The agent can be controlled with the following commands:
- `gopass age agent`: starts the agent in the foreground.
- `gopass age lock`: locks the agent, clearing all cached passphrases.
The age backend will automatically start the agent if it's not already running and the `age.agent-enabled` configuration option is set to `true` (the default).
This change includes:
- The implementation of the age agent in `internal/backend/crypto/age/agent/`.
- Modifications to the age backend to communicate with the agent.
- A new configuration option `age.agent-enabled`.
- Unit tests for the agent.
- Updated documentation for the age backend.
* Fix some test failures and add more logging.
Signed-off-by: Dominik Schulz <dominik.schulz@gauner.org>
* Fix lint error
Signed-off-by: Dominik Schulz <dominik.schulz@gauner.org>
* [fix] Fix integration tests
Signed-off-by: Dominik Schulz <dominik.schulz@gauner.org>
---------
Signed-off-by: Dominik Schulz <dominik.schulz@gauner.org>
Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
Co-authored-by: Dominik Schulz <dominik.schulz@gauner.org>
* specify ssh dir
Signed-off-by: Joel Lau <joellau@protonmail.com>
* added documentation, prefer GOPASS_SSHDIR
Signed-off-by: Joel Lau <joellau@protonmail.com>
* check for empty path
Signed-off-by: Joel Lau <joellau@protonmail.com>
---------
Signed-off-by: Joel Lau <joellau@protonmail.com>
* [FEATURE] Allow for non-interactive age setup
Also updates Go to Go 1.23.2 and get rid of min and max functions
Signed-off-by: Yolan Romailler <AnomalRoil@users.noreply.github.com>
* [n/a] also renaming clear for Windows
Signed-off-by: Yolan Romailler <AnomalRoil@users.noreply.github.com>
* [n/a] bumping our GHA to Go 1.23
Signed-off-by: Yolan Romailler <AnomalRoil@users.noreply.github.com>
* [n/a] make our harden runner softer
Signed-off-by: Yolan Romailler <AnomalRoil@users.noreply.github.com>
* [n/a] make our harden runner accept go.dev
Signed-off-by: Yolan Romailler <AnomalRoil@users.noreply.github.com>
* [n/a] applying code review changes
Signed-off-by: Yolan Romailler <AnomalRoil@users.noreply.github.com>
---------
Signed-off-by: Yolan Romailler <AnomalRoil@users.noreply.github.com>
This will be added to the per-store git config on newly
initialized stores.
RELEASE_NOTES=[ENHANCEMENT] Use persistent SSH connections
Signed-off-by: Dominik Schulz <dominik.schulz@gauner.org>
This backend has never been fully completed and shouldn't be used
as-is.
RELEASE_NOTES=[CLEANUP] Remove the ondisk backend
Signed-off-by: Dominik Schulz <dominik.schulz@gauner.org>