My take on the hyped trend of age verification laws going around lately. A simple helper that tells you the age bracket of the current user. I could slab this sucker into my custom built distro and take that law off my mind. That's it.
Why's not?
Storing age data safely is tricky:
- Needs to be readable by your app
- Shouldn't be modifiable by regular users
- Must work for all users on the system
whatmyage reads from a root-protected file (/etc/users.age) and outputs the user's age bracket. Your app doesn't need root; just call the tool and get the bracket.
0-1213-1516-1718-2021+
# Build
make
# Install (requires root)
sudo make install
# Add some users
echo "alice:2008" | sudo tee -a /etc/users.age
echo "bob:2012" | sudo tee -a /etc/users.age
# Test it
whatmyage
# Output: 18-20 (if you're alice and this year is 2026)username:year_of_birth
One entry per line. Simple.
Example:
alice:2008
bob:2012
admin:1990
The file must be:
- Owned by root
- Permissions
0600(read/write for root only)
The program will complain loudly if you get this wrong.
age=$(whatmyage)
echo "User is in bracket: $age"FILE *fp = popen("whatmyage", "r");
char buf[32];
if (fgets(buf, sizeof(buf), fp)) {
printf("Age bracket: %s", buf);
}
pclose(fp);import subprocess
result = subprocess.run(["whatmyage"], capture_output=True, text=True)
print(f"Age bracket: {result.stdout.strip()}")Works from any language that can run external commands. Even works with statically-linked binaries via popen().
make # build
make install # install to /usr/local/bin
make clean # clean upWant to install somewhere else?
sudo make install PREFIX=/usrCustom data file location?
make DATA_FILE=/usr/local/etc/users.age
sudo make install DATA_FILE=/usr/local/etc/users.ageOn first build, you can customize the installation with these options:
make DATA_FILE=/path/to/users.age ALLOW_USER_SET=0These settings are saved to config.mk and will be used automatically in subsequent builds.
Options:
DATA_FILE- Path to the data file (default:/etc/users.age)ALLOW_USER_SET- Allow non-root users to set their own year of birth (default:1)1- Users can set their own year with--set0- Only root can use--set
To change configuration, run make clean first to force a rebuild with new settings:
make clean && make DATA_FILE=/new/path ALLOW_USER_SET=0To start fresh (remove build artifacts and saved config):
make cleanUsers can set their own year of birth:
whatmyage --set 1990Root can set any user's year of birth:
sudo whatmyage --set 1990 usernameThis works similar to passwd - root manages user entries while regular users can only modify their own.
- Linux (glibc, musl)
- FreeBSD
- OpenBSD
- NetBSD
- macOS
- The binary is setuid root-it needs root to read the protected data file
- It clears the environment on startup
- It validates that
/etc/users.ageis owned by root with correct permissions - It drops privileges before doing anything else
Is it bypassable by root? Obviously-root can do anything including changing user passwords anddestroying systems if they want, and we worrying about age leaks, get real.
Copyright 2026 thaolt@songphi.com
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
-
Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
-
Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
-
Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS โAS ISโ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.