diff options
| author | Danilo M. <danix@danix.xyz> | 2026-11-05 10:22:12 +0100 |
|---|---|---|
| committer | Danilo M. <danix@danix.xyz> | 2026-11-05 10:22:12 +0100 |
| commit | 395eed25a9d879391558026bb90cd3acb9afdacf (patch) | |
| tree | 70e33dcdcca31fc47d595cd339778ebfa09ce6df /content/en | |
| parent | a5761e8d7875357d0dcc52a5cc31f06f866d791c (diff) | |
| download | danixxyz-395eed25a9d879391558026bb90cd3acb9afdacf.tar.gz danixxyz-395eed25a9d879391558026bb90cd3acb9afdacf.zip | |
content: write HardenedPass getting-started pages
Concepts, install, creating a store from zero and connecting the app, in
both languages, with screenshots from the test store. Still drafts.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Diffstat (limited to 'content/en')
| -rw-r--r-- | content/en/hardenedpass/getting-started/_index.md | 10 | ||||
| -rw-r--r-- | content/en/hardenedpass/getting-started/concepts/index.md | 68 | ||||
| -rw-r--r-- | content/en/hardenedpass/getting-started/connect/index.md | 81 | ||||
| -rw-r--r-- | content/en/hardenedpass/getting-started/connect/pgp-import.png | bin | 0 -> 106999 bytes | |||
| -rw-r--r-- | content/en/hardenedpass/getting-started/connect/repository.png | bin | 0 -> 99383 bytes | |||
| -rw-r--r-- | content/en/hardenedpass/getting-started/connect/ssh-key.png | bin | 0 -> 56540 bytes | |||
| -rw-r--r-- | content/en/hardenedpass/getting-started/connect/store-list.png | bin | 0 -> 58810 bytes | |||
| -rw-r--r-- | content/en/hardenedpass/getting-started/connect/welcome.png | bin | 0 -> 95692 bytes | |||
| -rw-r--r-- | content/en/hardenedpass/getting-started/create-store/index.md | 70 | ||||
| -rw-r--r-- | content/en/hardenedpass/getting-started/install/index.md | 60 |
10 files changed, 267 insertions, 22 deletions
diff --git a/content/en/hardenedpass/getting-started/_index.md b/content/en/hardenedpass/getting-started/_index.md index f825040..6aecc2d 100644 --- a/content/en/hardenedpass/getting-started/_index.md +++ b/content/en/hardenedpass/getting-started/_index.md @@ -1,13 +1,11 @@ +++ title = "Getting started" date = 2026-11-05T00:00:00Z -description = "" +description = "Start here: what pass is, how to install HardenedPass, how to make a password store and connect the app to it." weight = 10 draft = true +++ -Placeholder. - -## First heading - -Text. +Read these pages in order if you have never used `pass`. If you already have a store +in a git repository, install the app and go straight to +[Connect the app]({{< relref "/hardenedpass/getting-started/connect" >}}). diff --git a/content/en/hardenedpass/getting-started/concepts/index.md b/content/en/hardenedpass/getting-started/concepts/index.md index 063dde1..0e4f6c9 100644 --- a/content/en/hardenedpass/getting-started/concepts/index.md +++ b/content/en/hardenedpass/getting-started/concepts/index.md @@ -1,13 +1,73 @@ +++ title = "Concepts" date = 2026-11-05T00:00:00Z -description = "" +description = "The three things HardenedPass is built on, in plain words: pass stores passwords as files, OpenPGP encrypts them, git syncs them." weight = 10 draft = true +++ -Placeholder. +HardenedPass is built on three tools. You do not need to master any of them, but +knowing what each one does makes the rest of these pages easy to follow. -## First heading +## pass: one file per password -Text. +[pass](https://www.passwordstore.org/) is a password manager for Unix systems. It has +no database. Each password is a small encrypted file, and folders group them. That +folder tree is called the **store**. + +``` +store/ +├── .gpg-id +├── example.org.gpg +├── otp/ +│ └── example.com.gpg +└── work/ + └── mail.example.org.gpg +``` + +Once decrypted, an entry is plain text. The first line is the password, and anything +below it is extra information: + +``` +hunter2 +username: alice +url: https://example.org +``` + +HardenedPass reads those lines and shows them as separate fields. Any program that +understands `pass` can open the same store, so your passwords are never locked into +this app. + +## OpenPGP: the lock on each file + +Every entry is encrypted with [OpenPGP](https://www.gnupg.org/), using a **key pair**: + +- The **public key** locks files. It is not secret. +- The **private key** unlocks them. It never leaves your devices. +- The **passphrase** protects the private key, so a copy of the key file alone is + useless to whoever finds it. + +The `.gpg-id` file at the top of the store says which keys entries are encrypted for. + +{{< callout type="danger" title="Back up your private key" >}} +If you lose the private key or forget its passphrase, nobody can decrypt your store. +There is no reset. Keep a copy somewhere safe and offline. +{{< /callout >}} + +## git: sync and history + +[Git](https://git-scm.com/) tracks every change to the store and copies it between +devices through a **remote**, a repository on a server. You change an entry on the +phone, the app records the change and sends it to the remote, and your other devices +fetch it from there. Old versions stay in the history, so a mistake can be undone. + +The server only holds encrypted files, but it can read their **names**. Whoever runs +it can see that you have an entry called `example.org`. Use a private repository, on a +server you trust. + +## How it fits together + +1. On a computer you make a key pair, a store and a remote. +2. On the phone, HardenedPass clones the store from the remote. +3. You import the private key into the app. +4. The app decrypts entries when you open them, and syncs changes through git. diff --git a/content/en/hardenedpass/getting-started/connect/index.md b/content/en/hardenedpass/getting-started/connect/index.md index 067ec6a..87ca4f7 100644 --- a/content/en/hardenedpass/getting-started/connect/index.md +++ b/content/en/hardenedpass/getting-started/connect/index.md @@ -1,13 +1,86 @@ +++ title = "Connect the app" date = 2026-11-05T00:00:00Z -description = "" +description = "How to connect HardenedPass to your store: clone the repository, set up an SSH key or password, import your OpenPGP private key." weight = 40 draft = true +++ -Placeholder. +You need the address of your repository and the file with your private key. If you +have neither, start with [Create a store]({{< relref "/hardenedpass/getting-started/create-store" >}}). -## First heading +## Clone the store -Text. +Open the app and tap **Clone Remote Repo**. + +{{< image src="welcome.png" alt="Welcome screen with the buttons Clone Remote Repo, Create Local Repo and Settings." class="max-w-sm mx-auto rounded-lg border border-border" />}} + +Type the address of your repository in **Repository URL** and choose how to log in +under **Authentication Mode**. + +{{< image src="repository.png" alt="Repository information screen with the URL filled in and SSH key selected as authentication mode." class="max-w-sm mx-auto rounded-lg border border-border" />}} + +These address forms all work: + +| Form | Example | +|---|---| +| SSH, short | `git@git.example.org:store.git` | +| SSH, with a port | `ssh://git@git.example.org:2222/srv/git/store.git` | +| HTTPS | `https://git.example.org/you/store.git` | + +The app warns you about addresses that would not work well: a custom port without +`ssh://`, a port on an HTTPS address, which is not supported, and `git://`, which has +no encryption. + +### With an SSH key + +Tap **Manage** next to the SSH key line. + +{{< image src="ssh-key.png" alt="SSH key screen with the buttons Import SSH key and Generate SSH key pair." class="max-w-sm mx-auto rounded-lg border border-border" />}} + +- **Import SSH key** reads a private key you already have, from a file. +- **Generate SSH key pair** makes a new key on the phone. Ed25519 is the best choice + unless your server is old. **Protect with screen lock credential** makes the app + ask for your screen lock each time it uses the key. + +After generating, the app shows the public key. Add it to your git server, in the +same place you would add a key for a computer. Then go back and tap **Clone**. + +### With a password + +Choose **Password** and tap **Clone**. The app asks for the password when it connects, +and **Remember password** stores it encrypted on the phone. Many hosting services want +an access token here rather than your account password. + +### The server's identity + +On the first SSH connection the app saves the server's host key without asking, and +checks it on every connection after that. If the key changes, syncing stops with an +error. If you know why it changed, tap **Clear saved host key** on the repository +screen. If you do not, stop and find out first: someone could be impersonating your +server. + +## Import your private key + +Once the clone is done, the app shows which key the store is encrypted for, under +**Store recipients**. + +{{< image src="pgp-import.png" alt="Import PGP key screen listing the store's recipient key ID, with an Import PGP key button." class="max-w-sm mx-auto rounded-lg border border-border" />}} + +Tap **Import PGP key** and pick your key file. The app shows the ID of the imported +key: check that it matches. You can tap **Later** to skip this, but no entry can be +opened until a matching key is imported. + +The list of entries opens, and you are done. + +{{< image src="store-list.png" alt="The store list, showing the folders otp and work and the entry example.org." class="max-w-sm mx-auto rounded-lg border border-border" />}} + +Delete the key file from the phone's storage now, as +[Create a store]({{< relref "/hardenedpass/getting-started/create-store" >}}) explains. +The first time you open an entry, the app asks for the key's passphrase. + +## A store without a server + +**Create Local Repo** makes a store that lives only on the phone. Import your private +key, then tap it in the list to create the store for that key. You still need a key +made on a computer, and without a remote nothing protects you if the phone is lost. diff --git a/content/en/hardenedpass/getting-started/connect/pgp-import.png b/content/en/hardenedpass/getting-started/connect/pgp-import.png Binary files differnew file mode 100644 index 0000000..2b01266 --- /dev/null +++ b/content/en/hardenedpass/getting-started/connect/pgp-import.png diff --git a/content/en/hardenedpass/getting-started/connect/repository.png b/content/en/hardenedpass/getting-started/connect/repository.png Binary files differnew file mode 100644 index 0000000..7c2494a --- /dev/null +++ b/content/en/hardenedpass/getting-started/connect/repository.png diff --git a/content/en/hardenedpass/getting-started/connect/ssh-key.png b/content/en/hardenedpass/getting-started/connect/ssh-key.png Binary files differnew file mode 100644 index 0000000..d4d5887 --- /dev/null +++ b/content/en/hardenedpass/getting-started/connect/ssh-key.png diff --git a/content/en/hardenedpass/getting-started/connect/store-list.png b/content/en/hardenedpass/getting-started/connect/store-list.png Binary files differnew file mode 100644 index 0000000..dc99393 --- /dev/null +++ b/content/en/hardenedpass/getting-started/connect/store-list.png diff --git a/content/en/hardenedpass/getting-started/connect/welcome.png b/content/en/hardenedpass/getting-started/connect/welcome.png Binary files differnew file mode 100644 index 0000000..b32915a --- /dev/null +++ b/content/en/hardenedpass/getting-started/connect/welcome.png diff --git a/content/en/hardenedpass/getting-started/create-store/index.md b/content/en/hardenedpass/getting-started/create-store/index.md index 205e035..378123a 100644 --- a/content/en/hardenedpass/getting-started/create-store/index.md +++ b/content/en/hardenedpass/getting-started/create-store/index.md @@ -1,13 +1,75 @@ +++ title = "Create a store" date = 2026-11-05T00:00:00Z -description = "" +description = "How to create a password store from zero on a computer: make an OpenPGP key, initialize pass, add a private git remote and export the key." weight = 30 draft = true +++ -Placeholder. +If you already have a store in a git repository, skip to +[Connect the app]({{< relref "/hardenedpass/getting-started/connect" >}}). -## First heading +HardenedPass cannot generate OpenPGP keys, so you need a computer for this part, with +[GnuPG](https://www.gnupg.org/), [pass](https://www.passwordstore.org/) and +[git](https://git-scm.com/) installed. Most Linux distributions package all three. -Text. +## Make a key pair + +```bash +gpg --full-generate-key +``` + +Accept the default key type, enter your name and an address, and choose a strong +passphrase. You will type it often, so pick one you can remember. + +## Create the store + +Use the address you gave the key: + +```bash +pass init you@example.org +pass git init +``` + +The first command creates the store in `~/.password-store` and writes `.gpg-id`. The +second turns it into a git repository. + +Add a first entry so that you have something to test with. `-m` lets you type several +lines; finish with Ctrl+D: + +```bash +pass insert -m example.org +``` + +``` +hunter2 +username: alice +``` + +## Add a remote + +Create an **empty, private** repository on a git server you can reach over SSH or +HTTPS. A hosting service works, and so does a server of your own. Then connect the +store to it and send it there: + +```bash +pass git remote add origin git@git.example.org:store.git +pass git push -u origin HEAD +``` + +## Export the private key + +The phone needs a copy of the private key: + +```bash +gpg --armor --export-secret-keys you@example.org > private-key.asc +``` + +{{< callout type="warning" title="Handle this file with care" >}} +Move `private-key.asc` to the phone over USB, not through email or a cloud drive. +Delete every copy from the phone's storage and from the computer once the app has +imported it. The app keeps its own. +{{< /callout >}} + +Also keep a backup of the key offline, for example on an encrypted USB stick. See +[Concepts]({{< relref "/hardenedpass/getting-started/concepts" >}}) for why. diff --git a/content/en/hardenedpass/getting-started/install/index.md b/content/en/hardenedpass/getting-started/install/index.md index 116df07..627261e 100644 --- a/content/en/hardenedpass/getting-started/install/index.md +++ b/content/en/hardenedpass/getting-started/install/index.md @@ -1,13 +1,65 @@ +++ title = "Install" date = 2026-11-05T00:00:00Z -description = "" +description = "How to download the HardenedPass APK from GitHub Releases, verify its checksum and signing certificate, install it and update it." weight = 20 draft = true +++ -Placeholder. +HardenedPass needs Android 8 or newer and works without Google Play Services. It is +not on an app store: you install the APK from the project's releases. -## First heading +## Download -Text. +Open the [latest release](https://github.com/danixland/HardenedPass/releases/latest) +and download both files: + +- `HardenedPass_vX.Y.Z.apk`, the app +- `HardenedPass_vX.Y.Z.apk.sha256`, its checksum + +## Verify the download + +This step needs a computer, and it is worth doing: a password manager is a bad thing +to install from a tampered file. + +Check that the file arrived intact: + +```bash +sha256sum -c HardenedPass_vX.Y.Z.apk.sha256 +``` + +The output must end in `OK`. + +Then check who signed it. `apksigner` is part of the Android SDK build tools: + +```bash +apksigner verify --print-certs HardenedPass_vX.Y.Z.apk +``` + +The `certificate SHA-256 digest` line must read: + +``` +725016669e482f9ac371dee8df19a2a1b34fa76d1af05b2a23784725b1b49c83 +``` + +If either check fails, do not install the file. + +## Install + +Copy the APK to the phone and open it from the file manager. Android asks you to allow +installs from that app the first time. Allow it, install, then turn the permission off +again if you prefer. + +HardenedPass has its own application ID, so it installs next to Android Password Store +instead of replacing it. The two share no data: to move over, set HardenedPass up +as described in [Connect the app]({{< relref "/hardenedpass/getting-started/connect" >}}). + +## Update + +The app does not check for updates. To follow new versions, watch the +[releases page](https://github.com/danixland/HardenedPass/releases) or its +[Atom feed](https://github.com/danixland/HardenedPass/releases.atom). + +To update, verify the new APK the same way and install it over the old one. Your store +and keys stay in place. Android refuses an update signed with a different key, which +is one more check on top of yours. |
