HackerReposA FIELD GUIDE TO OPEN SOURCE
ProSponsor the shelf♧ 0
← Back to top all-time
FiloSottile
age
Go2019–2026
FiloSottile / age

age

A simple, modern and secure encryption tool (and Go library) with small explicit keys, no config options, and UNIX-style composability.

107Distinct people
126Mentions
1Explicit recommenders
24.3KGitHub stars
REPOSITORY AT A GLANCE

What to know before exploring

What it is

A simple, modern and secure encryption tool (and Go library) with small explicit keys, no config options, and UNIX-style composability.

GitHub

Where it is used

No documented product use was verified in the last source check.

What people are saying

I recommend age as well. It offers encrypting for recipients for whom you have public keys. https://github.com/FiloSottile/age

ChrisGranger used a recommendation phrase. One indexed comment matches. This is a phrase match, not a verdict.

No classified warning is attached to this page. Read the discussions before treating silence as approval.

Also in these discussions

Mentioned in the same Hacker News threads. That is not proof they are substitutes.

This week on Hacker News

Nov 7–Nov 14 UTC · Direct repository links and separately labeled related project stories. Indexed through 11/14/2026, 3:56:07 PM UTC.

No direct repository links were found in the indexed HN discussions over the past seven days. Older discussions are available below.

Mentions over time

HN mentions by year126 dated mentions

Observed mentions: 2019-10-07 03:21:46 UTC to 2026-10-10 15:30:33 UTC.

01020302019-01-01 00:00:00 UTC to 2020-01-01 00:00:00 UTC (exclusive): 11 mentions; 4 submissions, 7 comments20192020-01-01 00:00:00 UTC to 2021-01-01 00:00:00 UTC (exclusive): 15 mentions; 0 submissions, 15 comments2021-01-01 00:00:00 UTC to 2022-01-01 00:00:00 UTC (exclusive): 29 mentions; 7 submissions, 22 comments2022-01-01 00:00:00 UTC to 2023-01-01 00:00:00 UTC (exclusive): 24 mentions; 5 submissions, 19 comments20222023-01-01 00:00:00 UTC to 2024-01-01 00:00:00 UTC (exclusive): 12 mentions; 0 submissions, 12 comments2024-01-01 00:00:00 UTC to 2025-01-01 00:00:00 UTC (exclusive): 12 mentions; 2 submissions, 10 comments2025-01-01 00:00:00 UTC to 2026-01-01 00:00:00 UTC (exclusive): 16 mentions; 3 submissions, 13 comments2026-01-01 00:00:00 UTC to 2027-01-01 00:00:00 UTC (exclusive): 7 mentions; 2 submissions, 5 comments. Incomplete calendar period.2026*

* An incomplete calendar period is marked with an outlined bar. Its count is not directly comparable with a full period.

Counts come from the repository’s dated source evidence. Index cutoff: 2026-11-02 08:16:59 UTC.

View mention counts and date ranges
UTC ranges include their start and exclude their end. Select a period to filter the source evidence.
PeriodStart (UTC)End (exclusive, UTC)MentionsSubmissionsComments
20192019-01-01 00:00:00 UTC2020-01-01 00:00:00 UTC1147
20202020-01-01 00:00:00 UTC2021-01-01 00:00:00 UTC15015
20212021-01-01 00:00:00 UTC2022-01-01 00:00:00 UTC29722
20222022-01-01 00:00:00 UTC2023-01-01 00:00:00 UTC24519
20232023-01-01 00:00:00 UTC2024-01-01 00:00:00 UTC12012
20242024-01-01 00:00:00 UTC2025-01-01 00:00:00 UTC12210
20252025-01-01 00:00:00 UTC2026-01-01 00:00:00 UTC16313
2026 (partial)2026-01-01 00:00:00 UTC2027-01-01 00:00:00 UTC725

From the project README

An excerpt from the repository, fetched Nov 13, 2026.

Read the project’s introduction
age is a simple, modern and secure file encryption tool, format, and Go library. It features small explicit keys, post-quantum support, no config options, and UNIX-style composability. $ age-keygen -o key.txt Public key: age1ql3z7hjy54pw3hyww5ayyfg7zqgvc7w3j2elw8zmrj2kg5sfn9aqmcac8p $ tar cvz ~/data | age -r age1ql3z7hjy54pw3hyww5ayyfg7zqgvc7w3j2elw8zmrj2kg5sfn9aqmcac8p > data.tar.gz.age $ age --decrypt -i key.txt data.tar.gz.age > data.tar.gz 📜 The format specification is at age-encryption.org/v1. age was designed by @benjojo and @FiloSottile. 🦀 An alternative interoperable Rust implementation is available at github.com/str4d/rage. 🌍 Typage is a TypeScript implementation. It works in the browser, Node.js, Deno, and Bun. 🔑 Hardware PIV tokens such as YubiKeys are supported through the age-plugin-yubikey plugin. ✨ For more plugins, implementations, tools, and integrations, check out the awesome age list. 💬 The author pronounces it [aɡe̞] with a hard g, like GIF, and it's always spelled lowercase. Installation Homebrew (macOS or Linux) brew install age MacPorts port install age Windows winget install --id FiloSottile.age Alpine Linux v3.15+ apk add age Arch Linux pacman -S age Debian 12+ (Bookworm) apt install age Debian 11 (Bullseye) apt install age/bullseye-backports (enable backports for age v1.0.0+) Fedora 33+ dnf install age Gentoo Linux emerge app-crypt/age Guix System guix package -i age NixOS / Nix nix-env -i age openSUSE Tumbleweed zypper install age Ubuntu 22.04+ apt install age Void Linux xbps-install age FreeBSD pkg install age (security/age) OpenBSD 6.7+ pkg_add age (security/age) Chocolatey (Windows) choco install age.portable Scoop (Windows) scoop bucket add extras && scoop install age On Windows, Linux, macOS, and FreeBSD you can use the pre-built binaries. https://dl.filippo.io/age/latest?for=linux/amd64 https://dl.filippo.io/age/v1.3.2?for=darwin/arm64 ... If you download the pre-built binaries, you can check their Sigsum proofs. If your system has a supported version of Go, you can build from source. go install filippo.io/age/cmd/...@latest Help from new packagers is very welcome. Usage For the full documentation, read the age(1) man page. Usage: age [--encrypt] (-r RECIPIENT | -R PATH)... [--armor] [-o OUTPUT] [INPUT] age [--encrypt] --passphrase [--armor] [-o OUTPUT] [INPUT] age --decrypt [-i PATH]... [-o OUTPUT] [INPUT] Options: -e, --encrypt Encrypt the input to the output. Default if omitted. -d, --decrypt Decrypt the input to the output. -o, --output OUTPUT Write the result to the file at path OUTPUT. -a, --armor Encrypt to a PEM encoded format. -p, --passphrase Encrypt with a passphrase. -r, --recipient RECIPIENT Encrypt to the specified RECIPIENT. Can be repeated. -R, --recipients-file PATH Encrypt to recipients listed at PATH. Can be repeated. -i, --identity PATH Use the identity file at PATH. Can be repeated. --version Print the version. INPUT defaults to standard input, and OUTPUT defaults to standard output. If OUTPUT exists, it will be overwritten. RECIPIENT can be an age public key generated by age-keygen ("age1...") or an SSH public key ("ssh-ed25519 AAAA...", "ssh-rsa AAAA..."). Recipient files contain one or more recipients, one per line. Empty lines and lines starting with "#" are ignored as comments. "-" may be used to read recipients from standard input. Identity files contain one or more secret keys ("AGE-SECRET-KEY-1..."), one per line, or an SSH key. Empty lines and lines starting with "#" are ignored as comments. Passphrase encrypted age files can be used as identity files. Multiple key files can be provided, and any unused ones will be ignored. "-" may be used to read identities from standard input. When --encrypt is specified explicitly, -i can also be used to encrypt to an identity file symmetrically, instead or in addition to normal recipients. Multiple recipients Files can be encrypted to multiple recipients by repeating -r/--recipient. Every recipient will be able to decrypt the file. $ age -o example.jpg.age -r age1ql3z7hjy54pw3hyww5ayyfg7zqgvc7w3j2elw8zmrj2kg5sfn9aqmcac8p \ -r age1lggyhqrw2nlhcxprm67z43rta597azn8gknawjehu9d9dl0jq3yqqvfafg example.jpg Recipient files Multiple recipients can also be listed one per line in one or more files passed with the -R/--recipients-file flag. $ cat recipients.txt # Alice age1ql3z7hjy54pw3hyww5ayyfg7zqgvc7w3j2elw8zmrj2kg5sfn9aqmcac8p # Bob age1lggyhqrw2nlhcxprm67z43rta597azn8gknawjehu9d9dl0jq3yqqvfafg $ age -R recipients.txt example.jpg > example.jpg.age If the argument to -R (or -i) is -, the file is read from standard input. Post-quantum keys To generate hybrid post-quantum keys, which are secure against future quantum computer attacks, use the -pq flag with age-keygen. This may become the default in the future. Post-quantum identities start with AGE-SECRET-KEY-PQ-1... and recipients with age1pq1.... The recipients are unfortunately ~2000 characters long. $ age-keygen -pq -o key.txt $ ag
Read the full README on GitHub

What Hacker News says

126 sources
I do not like the idea of self-hosting VaultWarden because I generally do not like the idea of application software requiring so much random access memory for even the simplest tasks. So, my idea was to use something like pass[0] or passage[1] (pass[0] + age[2]) on a remote server, but the problem arises when Yubikeys come into play. I am in no way, shape, or form, endorsing this PonyApp thingy and cannot vouch for it as I haven't audited it. But judging by what it says on the tin, it does appear like a candidate to solve the specific problem I have. [0]: https://www.passwordstore.org/ [1]: https://github.com/FiloSottile/passage [2]: https://github.com/FiloSottile/age
In Bitwarden Dual License Model
That is true, but it's not specifically what makes it unique. Most encryption tool (like https://github.com/FiloSottile/age which is what secs-man uses under the hood) do not usually bake in the encryption key, rather they expect you to generate it and provide it. This is true for secs-man too: when you export it prompts with "Enter passphrase:" and you enter the passphrase (I am considering extending it to read the passphrase from a file or from an environment variable, or piped in from stdin, but I'm still not sure what to think of if from a security standing point and I they don't fit my current use so I don't have it in the current TODO) What makes it unique is that it can be completely emulated by hand (even though it might be a bit tedious) from just a terminal with bash and age installed. This is explained a bit better in the blog
Read the rest
post or in the "philosophy section" of the README, but the main point is that (in my opinion) you should NEVER find yourself vendor-locked-in for any data, in particular for secrets. However, you will always need tools for managing them. My tool is designed to be usable and avoid vendor-lock-in, meaning that even if you lose access to the tool you are not locked out of your tools! I have probably phrased it better in the linked blog post, I invite you to read it if you're still curious. I'm here for any other question!
In Show HN: Secs-man, a secrets manager you can (not) rely on
Or will they ban you from using something like https://github.com/filosottile/age to encrypt and armor text encode things you send inside of the non-encrypted chat? echo "Am I doing something illegal, France?" | age -e -r age1ql3z7hjy54pw3hyww5ayyfg7zqgvc7w3j2elw8zmrj2kg5sfn9aqmcac8p -a - -----BEGIN AGE ENCRYPTED FILE----- YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBjTVQ5VTdMaTlnRkEyT1BY MHZPc0lncHFvbS9FMTlDa2FkK3JQZy9sQnprClRFN3lNQUtnNzJWK0RxQVlYNE1q NCtlNFJTUWpwZExJSDMvSGlRL2VHc1EKLS0tIC95bEErRU9NNERJRVVuYlMwUFg4 WUx1R0IyTHd1d2dxQTdqU0NJWlF0MXMKL1x9fz+ZVObYrn3bY/IdVBsd4KYxn78P aWePVjaRUityGTkndNSy6gg1meVky22iv4rxd9MZ4XYnsGJDfRUmkVZhQcCxag== -----END AGE ENCRYPTED FILE-----
In France moves to break encrypted messaging
Really depends on your threat model and use case. The problems with .env files: plain text on disk, no access control, no rotation mechanism, no audit trail, trivial to leak accidentally, secrets go into env variables (which are exposed and often leak). Which of those do you care about? What are you trying to prevent? At the simplest level, keeping .env-ish files, use sops + age [1] or dotenvx [2] (or similar) to encrypt just the values. You keep the .env file approach, the actual secrets are encrypted, and now you can check the file in and track changes without leaking your secrets. You still have the env variable problems. There are some options that'll use virtual files to get your secrets from a vault to your process's env variables, or you can read the secrets from a secret manager yourself into env variables, but that feels like mor
Read the rest
e complexity without a lot more gain to me. YMMV. You could use a regular password manager (your OS's keychain, 1Password and its ilk, etc) if you're just working on your own. Also in the more complexity without much gain category for me. If you want to use a local file on disk, you could use a config file with locked down permissions, so at least it's not readable by anything that comes along. ssh style. Better is to have your code (because we're talking about your code, I assume) read from secret managers itself. Whether that's Bitwarden, AWS / GCP / Azure (well, maybe not Azure), Hashicorp, or one of the many other enterprisey options. That way you get an audit trail and easy rotation, plus no env variables and no plain text at rest. You can still leak them, but you have fewer ways to do so. Speaking of leaking accidentally, the two most common paths: Logging output and Docker files. The first is self explanatory, though don't forget about logging HTTP requests with auth headers that you don't want exposed. The second is missed by a lot of people. If you inject secrets into your Dockerfile via `ARG` or `ENV` that gets baked into the image and is easy to get back out. Use `--mount-type=secret` etc. (Never use the old Docker base64 stored secrets in config. That's just silly.) There are other permutations and in-between steps, these are just the big ones. Like all security stuff, the details really depend on your specific needs. It is easy to say, though, that plain text .env files injected into env variables are at the bad end of the spectrum. Passing the secrets in as plain text args on the command line is worse, so at least you're not doing that! 1: https://github.com/getsops/sops / https://github.com/FiloSottile/age 2: https://dotenvx.com
In Show HN: enveil – hide your .env secrets from prAIng eyes

Showing the 15 most recent of 126 sources. Enable JavaScript to search and browse every indexed mention.

MAKE YOURSELF AT HOME

A few shortcuts

/
Search the collection
?
Open this guide
Esc
Close dialogs and navigation

Your saved repositories and interests stay in this browser.