Time Based One-Time Passwords, with Vault
Everyone uses an authenticator app these days. Well, vault can provide the same service for your apps. Let’s create our own 2FA for our apps and see how convenient it is.
Goal: QR code, readable from an authenticator app and checking if its valid.
What we need
Let’s start by enabling the secrets engine for Time Based One-time Password (totp from now on).
You can type any path below, I forgot and left it default. Anywhere in the endpoints where it says totp will need to change to the root path you write.
While testing I came across an error when I selected my issuer in the below command with “-” character at the end by mistake. Read more about it here. Apparently Vault does not allow an issuer to have such a char in the end. ALSO Vault gives the same error if you are trying to access the wrong endpoint.
vault write --field=barcode totp/keys/test1 random_stuff=123 generate=true account_name=yigit issuer=my-super-vault-
vault write --field=barcode totp/keys/test1 random_stuff=123 generate=true account_name=yigit issuer=mysupervault
In the above command, the field=barcode allows us to only retrieve the base64 PNG data to create our QR code (we also get the url to auth if not). generate=true means we want to create a new one, account_name is another necessary part which can be your name (or anything you want) and the issuer can be anything we want but it is mandatory. The only extra data there is the random_stuff=123 key-value pair. test1 is our key name
If we were to decode this we would get,
Let’s pass this stuff to a PNG file and see what happens. The command itself is still the same except we added base64 conversion, and stuffing the result to a file. We could also manually save the result to a file and convert that as well.
vault write --field=barcode totp/keys/test1 random_stuff=123 generate=true account_name=yigit issuer=mysupervault | base64 -d > qr2.jpg
Now let’s try to use an authenticator to see if it works. I used authy and could create codes but authy didn’t allow screenshots so instead I’m opting with chrome authenticator addon from here. If we scan the QR with the authenticator, we should get yigit account added successfully.
Just go ahead and try reading the contents of the qr. What you get is a URL like below.
otpauth://totp/mysupervault:yigit?algorithm=SHA1&digits=6&issuer=mysupervault&period=30&secret=4K6XE7CQOZWNYOBRS4AEVCCSBNQRO5WF
We can also get this number from an app as below. We will be using the endpoint v1/totp/code/test1. totp is the root path we gave for our engine, test1 is the keyname we used throughout. Don’t mistake with mysupervault which is the issuer, like github.
Postman has an env var capability but it doesn’t use the one from the host but keeps a set for itself. Click the eye on the top right, and create your env vars. Then after you select the active environment (super env) you can your vars as {{name_of_var}}
Ignore the request body, GET method is enough.
Now let’s check if the number we got is valid. Same endpoint as before and in the request body we will be sending just the code.
Thanks for reading and see you next time.