{"id":16649789,"url":"https://github.com/william-stearns/trinkeypass","last_synced_at":"2025-04-09T17:05:37.954Z","repository":{"id":50028718,"uuid":"361322417","full_name":"william-stearns/trinkeypass","owner":"william-stearns","description":"Adafruit Neo Trinkey password safe","archived":false,"fork":false,"pushed_at":"2021-06-05T23:22:00.000Z","size":61,"stargazers_count":12,"open_issues_count":0,"forks_count":2,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-04-09T17:05:29.905Z","etag":null,"topics":["adafruit","adafruit-neopixel","circuitpython","gpl3","gplv3","keyboard","neopixels","password","password-store","python","python3"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/william-stearns.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2021-04-25T03:31:03.000Z","updated_at":"2025-03-13T16:26:43.000Z","dependencies_parsed_at":"2022-08-31T06:51:44.666Z","dependency_job_id":null,"html_url":"https://github.com/william-stearns/trinkeypass","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/william-stearns%2Ftrinkeypass","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/william-stearns%2Ftrinkeypass/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/william-stearns%2Ftrinkeypass/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/william-stearns%2Ftrinkeypass/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/william-stearns","download_url":"https://codeload.github.com/william-stearns/trinkeypass/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248074976,"owners_count":21043490,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["adafruit","adafruit-neopixel","circuitpython","gpl3","gplv3","keyboard","neopixels","password","password-store","python","python3"],"created_at":"2024-10-12T09:12:33.899Z","updated_at":"2025-04-09T17:05:37.931Z","avatar_url":"https://github.com/william-stearns.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# trinkeypass\nAdafruit Neo Trinkey password safe\n\n## Intro\n\n   Password managers and keys do a good job of authenticating us, but\neach has at least one passphrase for authentication.  I find I need a\nphysical store for these especially sensitive passwords, passphrases, and\npins.  For that, we have the TrinKeyPass - the world's smallest password\nvault.\n\n\n\n## Quickstart\n\n### Initial setup\n\n1. Buy an Adafruit Neo Trinkey (\u003chttps://adafru.it/4870\u003e , redirects to\n\u003chttps://www.adafruit.com/product/4870\u003e $6.95 ea., bulk discounts\navailable).  Better yet, buy 2 so you have a backup.\n\n2. These have USB-A connectors.  If you're looking to connect them to\nother USB connectors or a lightning connector, pease see Other Resources\nat the end.\n\n3. Download the firmware from \u003chttps://adafru.it/RD7\u003e , redirects to\n\u003chttps://circuitpython.org/board/neopixel_trinkey_m0/\u003e .  You need the\nmost recent 7.x UF2 file, which will download with a filename like\nadafruit-circuitpython-neopixel_trinkey_m0-en_US-7.0.0-alpha.2.uf2 .\n\u003chttps://adafruit-circuit-python.s3.amazonaws.com/bin/neopixel_trinkey_m0/en_US/adafruit-circuitpython-neopixel_trinkey_m0-en_US-7.0.0-alpha.2.uf2\u003e\nas of this writing.\n\n4. Insert the Trinkey into a USB port.  On a Mac - and possibly other\nplatforms too - the OS may note that a new keyboad and/or drive have been\ninserted.  Feel free to dismiss any windows asking you to identify the\nkeyboard.  If you're asked if you want to automatically mount the drive,\nI'd suggest Yes while you're going through this initial setup, then\nchange that to No when you're finished adding passwords.\n\n5. Tap the black reset button in the middle of the board **twice**.  The\n4 LEDs will turn green and the storage on the Trinkey will be\nautomatically mounted (under /Volumes/TRINKEYBOOT/ on a Mac.)\n\n6. Copy the .UF2 file into this directory.  All the LEDs will turn red,\nthat drive will automatically disconnect (and put up a harmless warning\nthat it disconnected without unmounting first).  After a few seconds it\nwill mount the real storage you need (on /Volumes/CIRCUITPY/ on a Mac).\n\n7. \"code.py\" is trinkeypass.py with comments removed.  Download code.py from\nhttps://raw.githubusercontent.com/william-stearns/trinkeypass/main/code.py\n, place it in this directory, and name it code.py.  Here's the command to\ndo it:\n\n```\ncd /Volumes/CIRCUITPY/\ncurl -fsSL https://raw.githubusercontent.com/william-stearns/trinkeypass/main/code.py -o code.py\ntouch .metadata_never_index\nsync\n```\n\n8. If you don't already have any password files (like 0000.txt and\n0001.txt), create 2 test \"password\" files for Trinkey to use:\n\n```\ncd /Volumes/CIRCUITPY/\necho \"This is a test password in 0000.txt.\" \u003e\u003e0000.txt\necho \"And here's another one in 0001.txt\" \u003e\u003e0001.txt\nsync\n```\n\n\n\n\n### Trinkeypass components\n\n1. You've already used the reset button, the black button between the\nLEDs and the largest chip.  If anything goes weird, tap it once to\nrestart the password safe software.\n\n2. There are 4 LEDs numbered 0-3.  LED 0 is next to the reset button. \nLEDs 1-3 are clockwise from LED 0.  When the trinkeypass software starts,\nit flashes the 4 LEDs in order in blue.\n\n3. There are two touch-sensitive pads, T1 and T2, at the far end from the\nUSB connector.  You'll tap one or both of these to get the Trinkey to do\nsomething.  T2 is on the same edge as the reset button, T1 on the\nopposite edge.  (The board has a \"1\" and a \"2\" silkscreened as reminders\nnext to the pads and the outermost LEDs.)\n\n\n\n### Using the password feature\n\n1. Click your mouse in a window where you can enter some text.  This can\nbe a graphical application (notepad/gedit) or a text window/terminal.  To\nsee what's returned without any chance of actually doing something, run\nthe command `cat \u003e/dev/null` to show and discard all keys.\n\n2. Press button T2 (the one on the same edge as the reset key).  This\nwill send the contents of 0000.txt to your computer as if you'd typed\nthose characters by hand on a USB keyboard.  The blue light next to the\nkeypad will flash to show you the button worked.  Try it a few more\ntimes.\n\n3. Now switch to the next password.  To do this, press button T1 - the\nLED next to it will flash briefly.  Now LED 0 will light green to\nindicate we're on a different key.  Press T2 and password *0001* will\ncome out into your selected window as if you typed it on a USB keyboard.\n\n4. If you press T1 again, this would move to the third key (in 0002.txt,\nif you had one).  Since you don't, it will go back to the beginning of\nthe list, 0000.txt .  Press T2 to confirm you're back on the first\npassword.\n\n5. The LEDs show you which key is selected.  Look at all the LEDs that\nare green and add up their values:\n\n* LED0 (next to the reset button) has a value of 1\n* LED1 (between LED0 and T2) has a value of 2\n* LED2 (next to T1) has a value of 4\n* LED3 has a value of 8\n\n   Add up the values for each LED that's lit; the sum is the number of\nthe key you're using.  That's why all LEDs are off when you're on Key\n0000.txt at start.  When you switch to the second key (0001.txt), LED0\nlights and all the rest are off.\n\n   When you get to the 17th password (0016.txt), the LEDs start back at\nall black since there are only 4 of them.  Similarly, when you get to the\n33rd password (0032.txt), they'll go back to black again.\n\n\n\n## Adding or editing passwords\n\n1. You can add more passwords or edit them at any time.  Each one goes in\nits own file starting with 0000.txt, 0001.txt, 0002.txt, etc.  \n\n2. Everything you place in the file is sent verbatim, so if you want a\nlinefeed at the end of a password to automatically submit it, make sure\nyou have a linefeed in the file.  If you want to just have the password\nkeys entered but want to manually edit them before pressing enter, leave\noff the linefeed.\n\n3. As soon as you save the file (and run the command `sync` on MacOS or\nLinux to make sure the changes are saved), the new password is ready to\nuse.  You don't have to restart or reinsert the key.\n\n4. The password files are named 0000.txt through 9999.txt, so you can\nhave up to 10,000 of them (though you'll run out of storage to hold those\nfiles before then).\n\n\n### Actually using this to enter passwords\n\n1. Save a real password/passphrase/pin to 0001.txt .  Press T1 until just\nLED0 is lit, indicating that you're on the 2nd password, 0001.txt .\n\n2. Start logging in; stop when you get to the password/passphrase/pin\nfield.\n\n3. Make sure your cursor is in the password/passphrase/pin box or window.\n\n4. Press T2 to type the characters from 0001.txt .  If that file ends in\na linefeed, the \"Enter\" key will be pressed and the password will be\nautomatically submitted.\n\n\n\n## Tips and tricks\n\n* If the key is loose in your USB port, place a folded post-it note under\nit (the side *away* from the USB contact pins) before inserting it into\nthe USB port.\n\n* This system can store and type any printable characters from your\nkeyboard.  This includes passwords, passphrases, pins, keys, and long\nblocks of text you commonly use (\"Thank you for writing in with your\ncomputer issue.  Have you tried rebooting it?  --Tech support\").\n\n* Use 0000.txt to store contact information, including \"How to return\nthis to me\" information should someone find it.\n\n* In 0001.txt place hints of what's stored in the other slots, like:\n\n```\n2  Password safe\n3  Home email\n4  Work email\n...\n```\n\n   If you forget what they are, go back to this slot 1 and press T2 to\nhave the hints come out in whatever window has keyboard focus.\n\n* Since this device can only give the barest of feedback of which key\nyou're on (the LEDs that indicate 0-15, and wrap around when they reach\nany multiple of 16), you might want to use a standard password vault like\nlastpass and reserve this for master passwords and key passphrases -\nthings you wouldn't normally want to place in a vault.\n\n* You can also use this drive to store key files, but we discourage\nplacing all factors needed to login on any single storage device\nincluding this one.\n\n* At the time of this writing (Apr 2021), it appears that circuitpython\nmay only support the US keyboard layout.  The authors are open to other\nlayouts.  For more info, see \n\u003chttps://github.com/adafruit/Adafruit_CircuitPython_HID/blob/master/adafruit_hid/keyboard_layout_us.py\u003e\n\n* You don't have to put the entire password in here.  If you have a way\nto mentally generate, say, the first 5 characters of a password based on\nthe hostname, type those into the password box by hand and enter the\n*remaining* letters that are stored in Trinkeypass.  Just remember that\nthe characters you type plus the characters provided by trinkeypass need\nto end up the same as what the remote system/application expect.\n\n* You could even split any given password between two trinkeys held by\ntwo different people for a particularly sensitive password.\n\n* It's a good idea to buy 2 or more of these and load your passwords on\nall of them.  You can keep one with you, perhaps in a wallet or on a\nkeyring, and place the others in safe locations.\n\n* This approach could be very handy for systems that are managed by\nmultiple people.  A Trinkeypass could hold a root/Administrator password,\ndatabase credentials, and any other credentials not needed in normal\noperation.  This could be passed from admin to admin on shift changes or\nstored in a central locked area.\n\n* To load an ssh private key into memory, put the following into one of\nyour password files.  The key won't be saved on disk, but be aware that\nthe content may be viewable by someone that looks at the list of running\nprocesses at the right moment.  Everything between the double quotes is\nyour private key.\n\n```\necho \"-----BEGIN RSA PRIVATE KEY-----\nMIIJJ...........\n...\n-----END RSA PRIVATE KEY-----\" | ssh-add -\n```\n\n   Go to a command prompt on a system running the ssh-agent.  Feed these\ncharacters into the shell and the key will be loaded into the ssh-agent.\n\n* You can enter more than one field on a web form.  Simply put your\nusername on the first line and put the password on the second line, both\nending in a linefeed.  Both will be entered.  (That's not as safe as now\nan attacker knows what account you have, but it's more convenient.)\n\n* If you hold down both T1 and T2 for longer than 7 seconds, everything\non the unit is erased.\n\n* Also, if you try to switch to a different password collection more than\n7 times (see below), everything on the unit is erased too.\n\n\n### Unlocking alternate password collections\n\n   By default, trinkeypass gets its passwords from files in the top level\ndirectory named 0000.txt, 0001.txt, and so on.  By creating directories\non the drive you can store alternate collections of password files and\nswitch between them.\n\n1. Create a directory called \"1212\" under /Volumes/CIRCUITPY/ .  In\n/Volumes/CIRCUITPY/1212/ , place a file called 0000.txt that has a\n_different_ password than the one immediately inside /Volumes/CIRCUITPY/\n.  Now create another file in the same directory called 0001.txt .\n\n2. To switch to this collection, press T1 and T2 at the same time to\nenter \"unlock\" mode (note that two LEDs turn yellow).  Since the\ndirectory you want to use is named \"1212\", press T1, T2, T1, and finally\nT2.  Now press T1 and T2 at the same time again to show you're done. \nYou've now switched to the new passwords.\n\n3. Press T2 to push out the current password.  Note that it's the one\ninside /Volumes/CIRCUITPY/1212/0000.txt , not the one in\n/Volumes/CIRCUITPY/0000.txt .\n\n4. To switch back to the top level directory, press T1 and T2, release\nthem, and press both again and release.\n\n5. You can have multiple directories like this, just name them with 1s\nand 2s and include at least one password file 0000.txt in each.  Now you\ncan break up your passwords into collections like:\n* Home\n* Master passwords\n* Production\n* SSH\n* Test\n\n6. Please make your directory names long so they're not easily guessed.\n\n7. Note that when the Trinkeypass first starts up it will feed out text\nfrom the files in /Volumes/CIRCUITPY/ without requiring you to enter any\nunlock code).  Because of this you may want to put dummy text in these\nfiles and put your real passwords in the subdirectories.  Example:\n```\n#Please return this to Bob Jones, 1 Main St, Springfield IL and I will mail you a $20 reward.\n```\n\n\n### Using the lockdown feature.\n\n   The Trinkey shares a drive that mounts on /Volumes/CIRCUITPY/ , which\nis exactly what you want when you want to update the code or edit any\npassword files.  This is not what you want forever because this makes the\nfiles visible to any person or program on the computer.\n\n   Once you're happy with the configuration and you no longer want to\nmake any changes, you can totally lock down the system (which will no\nlonger share the drive on which your unlock code and passwords are\nstored, as well as removing a few other features that might potentially\ngive an attacker access).  Make sure you've entered an unlock pin first,\nthen:\n\n1. Go to /Volumes/CIRCUITPY/\n\n2. Rename bootlockdown.py to boot.py\n\n3. Run \"sync\" and wait two seconds.\n\n4. Press Reset on top of the Trinkey.\n\n   From this point on the drive will no longer be visible.  There is no\nway to return to normal operation.\n\n\n\n\n\n## Risks\n\n* Note that if the system into which you've inserted the Trinkeypass is\nrunning a keyboard sniffer, that program will see the injected password\njust as easily as a password typed at an actual keyboard.\n\n* We discourage indexing or backing up this drive.\n\n* If you're using multiple factors to log in somewhere (such as a \npassword, an ssh key, and the passphrase to unlock that ssh key, please\ndo not store all factors in any single place (including on this Trinkey).\n\n\n---\n## Other resources\n\n* Adafruit document describing the Neo Trinkey:\n\u003chttps://learn.adafruit.com/adafruit-neo-trinkey\u003e\n\n* I've done tests on MacOS, Linux, and Windows 10 with success on all 3. \nI've tried web logins, ssh key loading, sudo password entry, and password\nlogin over ssh.  This password entry should work anywhere you can type\nkeystrokes with a normal keyboard.\n\n* To plug this into a USB-C port: USB-A -\u003e USB-C adaptor\n(\u003chttps://www.amazon.com/gp/product/B086WFD4V6/\u003e, $4.99 for a 4-pack). \n\n* To plug this into a microusb port:\n(\u003chttps://www.amazon.com/UGREEN-Adapter-Samsung-Controller-Android/dp/B00N9S9Z0G/\u003e,\n$7 for a 2-pack)\n\n* To plug this into a lightning port used on many iphones and ipads: the\nLightning to USB Camera adapter\n(\u003chttps://www.amazon.com/Apple-Lightning-USB3-Camera-Adapter/dp/B01F7KJDIM/\u003e\nfrom Apple, $35, supports USB3, or\n\u003chttps://www.amazon.com/Adapter-Charging-Portable-Compatible-Support/dp/B08LQ2K8RL/\u003e,\ngeneric, USB2 only, $13)\n    Note: my early tests with these have been unsuccessful.\n\n\n* To hook it to a keychain, order some small keychain rings like\n(\u003chttps://www.amazon.com/gp/product/B01MG68TV6/\u003e , $6.96 for a 200-pack)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwilliam-stearns%2Ftrinkeypass","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fwilliam-stearns%2Ftrinkeypass","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwilliam-stearns%2Ftrinkeypass/lists"}