~sircmpwn/himitsu

Daemon for storing secrets
Update README.md, RPC.md
Initial riggings for retrieve command
hiprompt-wl: handle optional keys

refs

master
browse  log 

clone

read-only
https://git.sr.ht/~sircmpwn/himitsu
read/write
git@git.sr.ht:~sircmpwn/himitsu

You can also use your local clone with git send-email.

#himitsu

Himitsu is a WORK IN PROGRESS system for storing secrets.

#The idea

Himitsu stores an encrypted list of records, each of which is a list of keys and values, some of which may be secret. Records are represented in a format inspired by Plan 9's ndb and factotum, and the same format is used both for representing records, querying for records, providing templates for incomplete records (which the user is expected to fill in), and so on.

The format of a record is a space-separated list of key/value pairs. Here's an example record with IRC credentials:

proto=irc host=irc.freenode.net nick=ddevault password!=hunter2

Single-quotes can be used to add spaces, and two single-quotes to escape a single-quote inline:

proto=example 'my key'='my value' myquote='a single -> '' <- quote'

Note that additional information beyond the password (such as the protocol, host, and nickname) are stored by Himitsu as well. The bang (!) indicates that the password field is a secret. In some contexts, it may be omitted for this reason, resulting in the following:

proto=irc host=irc.freenode.net nick=ddevault password!

This indicates that a password is expected, but is omitted in this context. Say that you'd like to implement an IRC client. You can connect to the RPC socket and query for all IRC credentials:

-> query proto=irc
<- key proto=irc host=irc.freenode.net nick=ddevault password!
<- key proto=irc host=chat.rizon.net nick=sircmpwn password!
<- key proto=irc host=example.org port=1337 nick=sircmpwn password!
<- end

If you'd like to read the passwords, you'd use the lookup command:

-> lookup proto=irc
<- key proto=irc host=irc.freenode.net nick=ddevault password!=hunter2
<- key proto=irc host=chat.rizon.net nick=sircmpwn password!=hunter2
<- key proto=irc host=example.org port=1337 nick=sircmpwn password!=hunter2
<- end

There'd be a delay between "lookup" command and the list of keys while the user is prompted for consent. Then, let's say that the user asks you to configure a new IRC network. You can issue the following command:

-> add proto=irc host port? nick password!

The user will be shown another prompt and asked to fill in the extra details, optionally generating a password. The question mark (?) for the port parameter indicates that it's optional; the user may choose to omit it. You can use optional and required parameters in your query, by the way, something like this:

-> query proto=irc host port? nick password!

This would only return results which have everything you need. Anyway, after the user fills out the new network details, it's returned back to you:

<- key proto=irc host=irc.freenode.net nick=ddevault password!=hunter2

And you can go ahead and establish the connection.

But wait! In this scenario, you're directly handling the user's credentials, and that's kind of shit. Let's instead do the following:

-> agent proto=irc
<- transfer proto=irc host=irc.freenode.net nick=ddevault password!
<- transfer proto=irc host=chat.rizon.net nick=ddevault password!
<- transfer proto=irc host=example.org port=1337 nick=ddevault password!
<- end

The agent command understands common protocols. In this example, the user is prompted to consent, then the daemon launches a special hiagent-irc command (or rather, any hiagent-$proto command) and passes it the user's cleartext password, as well as your Unix socket connection. The agent command connects to IRC and negotiates authentication with the remote server, and each transfer command returns a file descriptor to you in the Unix domain auxillary data which represents the established connection. Your IRC client takes the file descriptor and assumes control over the connection, and you've successfully connected to IRC without ever seeing the user's password.