CLEVIS-ENCRYPT-TAN(1)
β¨ CLEVIS-ENCRYPT-TAN β¨
okay so bestie, clevis-encrypt-tan β wait, no, it's clevis-encrypt-tang(1) β is the manual page for encrypting stuff with a Tang binding server policy. yes we're doing cryptography today and yes you're gonna slay it π
πΈ NAME πΈ
clevis-encrypt-tang β encrypts using a Tang binding server policy π
π¦ SYNOPSIS π¦
clevis encrypt tang CONFIG [-y] < PT > JWE
π OVERVIEW π
so the clevis encrypt tang command encrypts your data using a Tang binding server policy. it takes literally one argument and that argument is a JSON configuration object. that's it. that's the whole vibe.
Clevis has your back with support for the Tang network binding server. and what does Tang give you? a stateless, lightweight alternative to escrows. iconic behavior honestly. here's how encrypting with the Tang pin goes down:
$ clevis encrypt tang '{"url":"http://tang.srv"}' < PT > JWE
The advertisement contains the following signing keys:
_OsIk0T-E2l6qjfdDiwVmidoZjA
Do you wish to trust these keys? [ynYN] y
and then to decrypt it? literally just hand it over to the clevis decrypt command, no drama:
$ clevis decrypt < JWE > PT
okay so as you can see up there βοΈ Tang runs on a trust-on-first-use workflow. but if you already know the thumbprint of a key you trust, you can just say so at encryption time instead of getting the whole interrogation:
$ cfg='{"url":"http://tang.srv","thp":"_OsIk0T-E2l6qjfdDiwVmidoZjA"}'
$ clevis encrypt tang "$cfg" < PT > JWE
and how do you even get the thumbprint of a trusted signing key? easy peasy. if you can get at the Tang server, just run:
$ tang-show-keys <PORT>
where <PORT> is the port the Tang server is listening on. noted. π
but say tang-show-keys isn't available and you do have access to the Tang server's database directory β no problem, run this instead:
$ jose jwk thp -i $DBDIR/$SIG.jwk
and here's the part where Tang gets extra β¨: it can do entirely offline encryption if you pre-share the server advertisement. you can grab that advertisement with one simple command β just be careful your network isn't compromised, fr fr, that's a real warning:
$ curl -f $URL/adv > adv.jws
once you've got that advertisement file, just provide it:
$ clevis encrypt tang '{"url":...,"adv":"adv.jws"}' < PT > JWE
π CONFIG π
this command uses these configuration properties, bestie:
url(string) β the base URL of the Tang server. this one is REQUIRED, no skipping it πthp(string) β the thumbprint of a trusted signing keyadv(string) β a filename containing a trusted advertisementadv(object) β a trusted advertisement (raw JSON)cacert(string) β path to a CA bundle used to verify the Tang server's TLS certificate (it gets passed tocurlas--cacert). you only need this when the server certificate is signed by a CA that is not in the system trust storecert(string) β path to the client TLS certificate used for mutual TLS (mTLS) authentication (passed tocurlas--cert)key(string) β path to the private key for the client TLS certificate (passed tocurlas--key). you can omit this one if the private key is already bundled inside the cert file
so cacert, cert and key are all optional. when none of them are set, Clevis talks to the Tang server exactly like it always did β plain HTTP/HTTPS with default CA verification, no notes. also important: these properties are file paths, not secrets, and they get stored in the JWE header so that decryption reuses them automatically. slay. π«Ά
Note when you're using this for automatic unlocking at boot (like with LUKS, iykyk), those referenced certificate and key files have to also be present at the same paths inside the initramfs, because that's where decryption actually happens. don't forget them or it's not gonna unlock, and you're gonna have a bad time π
π MTLS EXAMPLE π
$ cfg='{"url":"https://tang.srv","cacert":"/etc/clevis/ca.crt",
"cert":"/etc/clevis/client.crt","key":"/etc/clevis/client.key"}'
$ clevis encrypt tang "$cfg" < PT > JWE
π₯ MTLS SECURITY MODEL π₯
okay this part is highkey important so listen up.
the cacert, cert and key properties get stored in the JWE protected header, which is integrity-protected by the AES-256-GCM authentication tag. so if anyone messes with any of those values, decryption will fail. periodt.
BUT β and this is the big but β that integrity check only happens after those values have already been used to contact the Tang server. why? because the decryption key is needed to verify the tag, and the Tang server has to be contacted to derive that key. so what does that mean for you? it means a tampered JWE will make the system fail to unlock, but one curl request will have already been sent using the tampered parameters. π
so to limit the exposure of that single request: store the JWE and any cacert, cert and key files it references in root-owned locations that are not writable by untrusted users, so the parameters can't be tampered with in the first place. that's the move.
you might also prefer installing the Tang server's CA into the system trust store (for example with update-ca-trust or update-ca-certificates) and then simply omitting cacert. also a valid move. pick your fighter β¨
β OPTIONS β
-yβ automatically answer yes for all questions. use this one to skip the advertisement trust check. super useful in automated deployments:
$ clevis encrypt tang '{"url":...}' -y < PT > JWE
π SEE ALSO π
clevis-decrypt(1) β go read that one next bestie, it's the whole other half of this story π¦
and that's the page!! you're officially good at Tang now, no cap. go encrypt something and feel like the main character π
this was CLEVIS-ENCRYPT-TAN(1), dated 10/16/2026 β catch you in the next manpage, mwah πβ¨
π¦ where this page comes from
- fedora 44: clevis 24-1.fc44 Β· GPL-3.0-or-later
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms