Remove guides and additional content

This commit is contained in:
Yarmo Mackenbach 2021-11-07 16:14:21 +01:00
parent 5bb7ba73cc
commit 30db350f99
No known key found for this signature in database
GPG key ID: 37367F4AF4087AD1
36 changed files with 1 additions and 2177 deletions

View file

@ -1,178 +0,0 @@
There is a lot to Keyoxide and decentralized identity verification, so let's divide the knowledge in three sections of increasing complexity.
[[toc]]
## Basic
Keyoxide allows you to prove "ownership" of accounts on websites, domain names, IM, etc., regardless of your username.
That last part is important: you could, for example, be 'alice' on Lobste.rs, but '@alice24' on Twitter. And if your website is 'thatcoder.tld', how are people supposed to know that all that online property is yours?
Of course, one could opt for full anonymity! In which case, keep these properties as separated as possible.
But if you'd like these properties to be linked and, by doing so, establish an online identity, you'll need a clever solution.
Enter Keyoxide.
When you visit someone's Keyoxide profile and see a green tick next to an account on some website, it was proven beyond doubt that the same person who set up this profile also holds that account.
## Intermediate
Keyoxide's purpose is just that: linking online properties together. Now, many services could easily claim they could accomplish the same feat. To ensure it happens in a trustworthy manner, Keyoxide uses an "open source, decentralized and cryptography-based approach to bidirectional linking".
Let's break down that sentence.
### Open source
Open source means: everyone can inspect the code behind Keyoxide. Really! Here, have a look at the code behind this website: [https://codeberg.org/keyoxide/web](https://codeberg.org/keyoxide/web). In fact, here is the code for the page you are currently reading: [content/about.md](https://codeberg.org/keyoxide/keyoxide-web/src/branch/main/content/about.md).
Not only can you look at it, you are allowed to make changes and even "fork it": take all this code and build your own product with it. Allowed? You are invited to! This keeps the Keyoxide project honest and always moving towards something that is better for everyone.
"Doesn't open source make it easier for others to steal your idea and your revenue?" Ah, good ol' capitalism. No. More about funding and the flow of money in the [Advanced](#advanced) section.
The Keyoxide project is licensed under [AGPL-3.0-or-later](https://codeberg.org/keyoxide/web/src/branch/main/LICENSE).
### Decentralized
The topic of decentralization is vast and complex. In short, it refers to the practice of keeping data in separate but connected places, instead of putting all the data in one single place.
Have you noticed how Google, Facebook and banks are desired targets for hackers? That is because they all use a centralized model. Break in once, get all the data. Of course, breaking in is difficult. But not impossible.
Keyoxide uses decentralization on two levels: the profile data, and the identity verification process.
#### Decentralized profile data
Where does Keyoxide get the data from to generate the profile pages? To make a Facebook profile, you need to give your data to them. Is this the same? Rest assured, Keyoxide does not want your data.
You put your data in a so-called cryptographic key. For our purposes, let's consider this a "glass vault". Everyone (including Keyoxide) can look inside the glass vault and see your data, but no one except you can change it or delete it. You have full control over your data. You can store it where you want: on a dedicated "key server", on your own server. You can even put it in a little piece of text!
```
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA512
Hey there! Here's a signature profile with proofs related to the DOIP project (https://doip.rocks).
Verify this profile at https://keyoxide.org/sig
proof=dns:doip.rocks
proof=https://fosstodon.org/@keyoxide
-----BEGIN PGP SIGNATURE-----
iQHEBAEBCgAuFiEENjcgJSPnwTCat56Z7y3FgntEX0sFAl/7L0MQHHRlc3RAZG9p
cC5yb2NrcwAKCRDvLcWCe0RfS3iYC/0QQqz2lzSNrkApdIN9OJFfd/sP2qeGr/uH
98YHa+ucwBxer6yrAaTYYuBJg1uyzdxQhqF2jWno7FwN4crnj15AN5XGemjpmqat
py9wG6vCVjC81q/BWMIMZ7RJ/m8F8Kz556xHiU8KbqLNDqFVcT35/PhJsw71XVCI
N3HgrgD7CY/vIsZ3WIH7mne3q9O7X4TJQtFoZZ/l9lKj7qk3LrSFnL6q+JxUr2Im
xfYZKaSz6lmLf+vfPc59JuQtV1z0HSNDQkpKEjmLeIlc+ZNAdSQRjkfi+UDK7eKV
KGOlkcslroJO6rT3ruqx9L3hHtrM8dKQFgtRSaofB51HCyhNzmipbBHnLnKQrcf6
o8nn9OkP7F9NfbBE6xYIUCkgnv1lQbzeXsLLVuEKMW8bvZOmI7jTcthqnwzEIHj/
G4p+zPGgO+6Pzuhn47fxH+QZ0KPA8o2vx0DvOkZT6HEqG+EqpIoC/a7wD68n789c
K2NLCVb9oIGarPfhIdPV3QbrA5eXRRQ=
=QyNy
-----END PGP SIGNATURE-----
```
This text above is all the data Keyoxide needs to generate a profile page. Everyone can read it. But no one can modify it. Change a single character in the text above and the signature gets invalidated.
A true "glass vault".
#### Decentralized identity verification
The process itself of verifying identities (more on this in the [bidirectional linking](#bidirectional-linking) section) is also decentralized. You do not need to contact Keyoxide servers for most verifications.
A Hackernews account can be verified by looking at the content of its "about" section. Most Fediverse accounts can be verified by looking at their "biography" section.
If you view a profile page on this website, your browser handles the identity verification by directly contacting Hackernews and the Fediverse. No intermediary servers required.
If you run `keyoxide verify ...` in a terminal, your computer handles the identity verification directly, not some server.
Once Keyoxide apps for mobile devices are developed (no ETA yet), your mobile device will handle the identity verification directly, not some server.
The less intermediary servers are required, the more trustworthy the process becomes.
Note: there are some exceptions to this when it comes to browsers, more on this in the [proxy](#proxy) section.
### Cryptography
Proofs are created and managed inside cryptographic keys that act as "secure transport vessels", which are stored on special servers that already contain the cryptographic keys of many people. Keyoxide simply goes looking for your key and reads the content.
What makes cryptographic keys so useful for us is that they are actually made of two keys: a "private key" and a "public key".
Everyone has access to the public key. This is the "glass vault" itself: everyone can see it, but no one can modify its content. You can safely share your public key.
The "glass vault" can only be opened and modified using the private key, which is usually nothing more than a file with seemingly random characters. The private key is yours and yours alone, and should never be shared.
It goes without saying that losing the private key means losing access to the public key. Likewise, someone who steals your private key can easily modify the contents of your public key. Handling cryptographic keys is no simple task, a process where security always takes precedence over convenience.
Keyoxide uses the widely-used and well-known [OpenPGP standard](https://www.openpgp.org).
You'll find guidance over on the [Getting started](/getting-started) page.
### Bidirectional linking
How does one prove they have control over two online properties?
Let's consider this slightly unusual scenario: how could I prove I own a car? We do not want to use any government services (which are centralized) so checking license plates is out of the question. I would also like to remain anonymous, so identity cards are also a no-go.
Obviously, I can't link the car to my person without revealing my identity. But what if I could link it to my house? That way, "whoever owns this house also owns this car". I establish an identity (I own this house and I own this car) without ever revealing my identity.
All I need to do is place a note behind a window of my home with the license plate on it. "Behind a window", not "outside": a glass vault! Everyone can read it, but only the person with the house keys can modify it.
I have now claimed my car in a fully decentralized manner, no need to involve any centralized organization. Is this sufficient? Yes and no. Only I could have placed that note there so that proves beyond doubt my access to the house.
But what if my neighbor puts my license plate on a note in their home? Their attempt at impersonation is an attempt at claiming ownership over my car.
This is why we can only trust bidirectional linking: not only does my home need a note behind a window with the car's license plate on it, my car needs a note under the windshield with my address on it. The neighbor can no longer be claim ownership over my car, as the car's note clearly states my home address, not theirs.
An unusual scenario indeed, but one that simplifies the stakes. Keyoxide allows you to establish an online identity while remaining anonymous: no one needs to know you are, but you can still prove you hold accounts on different websites.
## Advanced
By now, you should have all the knowledge to understand what is going on and get started. Here are a few more advanced (and optional) topics.
### Proxy
This section involves almost exclusively Keyoxide's web client (the website you are currently viewing). Native clients (like the [Keyoxide CLI](https://codeberg.org/keyoxide/cli)) do not need a proxy under normal circumstances.
Some services like Gitlab or DNS require complicated verification processes or code that cannot be run in a browser. In such cases, the browser will ask a Keyoxide server to do the verification instead.
Since this is the internet we are talking about, you should always be skeptical about data that comes from some unknown server. In order to mitigate this, each profile page on this website will invite you to perform the identity verification again but locally, using a native client appropriate to your device if one exists.
### Claims
Claims are the pieces of data to lets you claim an online property. A claim can only be verified by a proof.
Claims are stored inside cryptographic keys as so-called "notations": these can be seen as custom data entries. Typically, claims are structured as follows:
```
proof@metacode.biz=https://platform.com/username
```
- *proof* tells us we are looking at the location of a potential proof the current claim.
- *@metacode.biz* tells us this is a specific type of proof, as defined on the [metacode.biz website](https://metacode.biz/openpgp/proofs). This part should NOT be changed when adding a new proof to your key.
- The rest of the proof is simply a URL to the profile page of your account on a website.
It is important to note that not all websites are supported. For now, supporting a single online platform involves a bit of work. It is also important to note not all platforms can be supported. You can always suggest new platforms to support by [creating an issue here](https://codeberg.org/keyoxide/doipjs) or contacting me at [yarmo@keyoxide.org](mailto:yarmo@keyoxide.org).
### Keyoxide instances
The Keyoxide website was built with the idea that other people could put it on their servers as well. We call these "instances". The Keyoxide project's lead developer has put an instance on [https://keyoxide.org](https://keyoxide.org) but that is not the only way to access Keyoxide. Everyone could put it on their servers.
Yes, another layer of decentralization.
The idea is simple: you will most likely not know the lead developer, so why should you trust his website [https://keyoxide.org](https://keyoxide.org)? By making the Keyoxide website selfhostable, you could put it yourself on your own server, or ask a friend to put it on theirs.
Ultimately, any Keyoxide website/instance is potentially compromised and any identity verification should be performed locally to get the most trustworthy results.
### Funding and the flow of money
With surveillance capitalism on the rise, it's important to understand where money comes from, especially with a project that involves online identity!
The project is fully funded by donations. There are no fees to using or hosting Keyoxide. There are no ads. There is no tracking. There are no investors.
All donations come from the people and the organizations that see the need for a project like Keyoxide to exist and be universally accessible.
Donations go to the [Key To Identity Foundation](https://keytoidentity.foundation/), founded by the lead developer for the purpose of promoting and sustaining the Keyoxide projects and other future identity-enhancing projects.
If you'd like to donate as well, please have a look at the [foundation's donate page](https://keytoidentity.foundation/donate). All contributions are much appreciated and help the lead developer to fully commit to the Keyoxide project.

View file

@ -1,78 +0,0 @@
[[toc]]
## What is Keyoxide?
Keyoxide is a modern and privacy-friendly platform to establish your decentralized online identity. It is fully Open Source under an AGPLv3 license and it can even be self-hosted. It can also perform basic cryptographic operations like encryption and signature verification.
## Who is Yarmo Mackenbach?
Hey, I am the lead developer for the Keyoxide project, which I am able to work on full-time thanks to the donations of those supporting the cause.
You can contact me at [yarmo@keyoxide.org](mailto:yarmo@keyoxide.org). My website is [yarmo.eu](https://yarmo.eu).
## Why does Keyoxide exist?
Keyoxide helps solve a growing issue on today's internet: **identity**.
During the *Web 1.0* days of the internet shortly after its inception, it served as a new world for people to explore. **Anonymity** reigned as all websites were silos: you could be two completely different personas on two different sites. You could even have different personas on the same website. There was no method to link personas to our real-world identity, nor a reason to.
Entered the *Web 2.0*. Small sites disappeared as large corporations took over. Facebook, Google, Amazon. Creating an account on those platforms had a lot of implications: that single account could be used across their different services and with the creation of "Login with X" buttons, even across different websites. People gave these platforms their personal information, a name, a phone number. That one account defined who you were on the internet. The corporation behind the platform had become the guardian of our online **identity**. As the internet slowly invaded our real-world lives, so did these platforms. We trusted them. We became complacent.
We know better now. These internet corporations gave us convenience with one hand and took away our privacy with the other. But we are getting a third chance.
Developers all over the world are building the *Web 3.0*, a new vision of the internet where its citizens keep control over their data and, by extension, their **identity**. The internet is only growing bigger and becoming a larger part of our lives. This new Web will have a strong focus on both **anonymity** and **identity**. Keyoxide is here to help with the latter.
While **anonymity** is the art of keeping a persona devoid of individualizing characteristics or qualities, **identity** is the science of tying online entities together, making sure the world can see these entities are part of a larger persona. A person can have multiple personas, or online **identities**.
## How does Keyoxide work?
Please have a look at the [About Keyoxide](/about) page.
## How does Keyoxide fit in the Web 3.0?
The one word to associate with the Web 3.0 is **decentralization**. This indirectly refers to the process of separating applications from data.
This means that while Keyoxide (the application) does the verification of your identity, it should not store that identity on its server! The data associated with your identity is stored in a different place where you keep control over it, typically a dedicated key server. We strongly recommend [keys.openpgp.org](https://keys.openpgp.org/) which is the default key server Keyoxide.
## How can I make an account?
You can't and that is the whole point of Keyoxide. Your data and your keys are not stored on our server. Therefore, there is no need to create an account. You simply [create a cryptographic keypair](/getting-started) and upload it to a dedicated key server. Keyoxide will automatically fetch your key only when needed.
## Can I get a sweet profile page?
That, we can help you with! Just append the fingerprint of your keypair to the domain like so: [https://${domain}/3637202523e7c1309ab79e99ef2dc5827b445f4b](/3637202523e7c1309ab79e99ef2dc5827b445f4b) to generate a profile page.
## Where is my profile avatar?
There are currently two methods of getting an avatar displayed on your profile page:
1. automatically fetched from [Libravatar](https://www.libravatar.org/) using your primary email address;
2. extracted from the public key.
While the first method is the simplest, the slightly-more-complicated second method provides an additional layer of privacy protection by not having to upload your profile picture to a 3rd party.
One caveat: [keys.openpgp.org](https://keys.openpgp.org) strips images from public keys. So the second method will only work in conjunction with [Web Key Directory](/guides/web-key-directory).
## Where do I upload my private key?
**DON'T**! We don't want it!
Alternative services may ask you for your private keys so that they can offer additional functionality. Please understand that your private key is yours and ONLY yours. You should never upload it to any online service, in fact it should never leave your computer.
## Where is the app?
There is no app yet. This is on the [roadmap](#what-is-on-the-roadmap%3F).
## PGP must die!
Not a question but we get your point. While there are [legitimate reasons PGP should not be used for use cases like communication](https://restoreprivacy.com/let-pgp-die/), it is still widely used and is actually quite a good fit for decentralized identity management.
But yes, try to avoid OpenPGP for communication. There are plenty of (decentralized) encrypted messaging platforms out there much better suited to that task.
## What is on the roadmap?
- Create apps
- Create an API
- Make Keyoxide more accessible (a11y and i18n)
- Support more platforms and services
- Integrate other encryption programs

View file

@ -1,142 +0,0 @@
Glad you made it here!
If you'd like to know more about how Keyoxide works before getting started, please have a look at the [About Keyoxide](/about) page.
Let's get you started on setting up your online identity and profile page.
[[toc]]
## Creating an account
Well, you can't.
But you don't need to!
Keyoxide is not your typical "web application" requiring you to create an account and log in to perform tasks. That sounds strange but this approach has many advantages!
If you'd like to know more about the theoretical concepts, have a look at the [About Keyoxide page](/about).
## Generating an OpenPGP key
**!!! Working with OpenPGP keys and identity proofs requires you to work with the command line !!!**
You only need to generate an OpenPGP key once. After this step, you will add and remove proofs using always the same key.
Install the **gpg** tool. It comes pre-installed with most Linux distributions.
Generate a new cryptographic key:
```
gpg --full-gen-key
```
Choose **RSA and RSA** by just pressing enter:
```
Please select what kind of key you want:
(1) RSA and RSA (default)
(2) DSA and Elgamal
(3) DSA (sign only)
(4) RSA (sign only)
(14) Existing key from card
Your selection?
```
Choose **2048** by just pressing enter:
```
RSA keys may be between 1024 and 4096 bits long.
What keysize do you want? (2048)
```
Choose **2y** to make your key valid for two years (it's simple to extend this period):
```Please specify how long the key should be valid.
0 = key does not expire
<n> = key expires in n days
<n>w = key expires in n weeks
<n>m = key expires in n months
<n>y = key expires in n years
Key is valid for? (0) 2y
```
Confirm this:
```
Key expires at Sun 28 Aug 2022 01:23:45 AM CEST
Is this correct? (y/N) y
```
Now, enter your name and email address (you can leave the comment empty):
```
GnuPG needs to construct a user ID to identify your key.
Real name: Alice Bobsdottir
Email address: alice@bobsdottir.net
Comment:
```
This email needs to be valid! You will receive an email later in this process.
Confirm this:
```
You selected this USER-ID:
"Alice Bobsdottir <alice@bobsdottir.net>"
Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? o
```
The next screen asks you to input a password to secure the key. Please use a long but memorable password and save it using a password manager: if you lose this password, you won't be able to edit the proofs in the future.
Once you confirm your password, the following message appears:
```
We need to generate a lot of random bytes. It is a good idea to perform
some other action (type on the keyboard, move the mouse, utilize the
disks) during the prime generation; this gives the random number
generator a better chance to gain enough entropy.
```
Once this is done, you have generated your OpenPGP key! To find your so-called **fingerprint**, run:
```
gpg --fingerprint
```
One of the first lines consists of 10 blocks of 4 hexadecimal characters: this is your **fingerprint**, the identifier that is globally unique to your key. Write it down somewhere or remember how you can make it appear, you will need it later.
## Uploading your key
Your computer now has a cryptographic keypair: both the private key and the public key. Next, we upload your public key to a special server whose only purpose is to contain the public keys of many people.
### First time
Export the public key to a file named **pubkey.asc** (make sure to replace EMAIL):
```
gpg --armor --export EMAIL > pubkey.asc
```
Go to [keys.openpgp.org/upload](https://keys.openpgp.org/upload) and upload your key using the form.
To prove ownership of the email address you entered in the key, the server will send you an email asking you to confirm by clicking a link. Once this process is done, it does not need to be repeated and uploading becomes a lot simpler by following the instructions below.
### Subsequent times
Simply run:
```
gpg --keyserver hkps://keys.openpgp.org --send-keys FINGERPRINT`
```
I told you we were going to need that fingerprint! Replace the FINGERPRINT above with yours (remove all spaces!).
## Adding a proof
By the way, you now already have a Keyoxide profile! Go to the [URL generator](/util/profile-url), choose **keys.openpgp.org** as source and enter your fingerprint (once again without spaces) and voilà! There's the URL. Visit it by copy-pasting inside the navigation bar of your browser.
Let's spice up that profile page with a proof. Adding a proof always requires you to do two steps:
- telling your online account on some website about your key
- telling your key about that account on some website
By performing an action on both your online account and inside your key, Keyoxide can prove for you that you have control over both the online account and the key. Go to the [Guides](/guides) and find one that suits the online account you wish to prove: this could be a [Twitter](/guides/twitter), [Mastodon](/guides/mastodon) or [GitHub](/guides/github) account.
Important note: all proofs stored inside keys start with **proof@metacode.biz=**. Never change this part!
Once you've uploaded your key again as per the guide's instructions, reload your profile page: it should now have your shiny new proof with a green **Verified** label next to it. Congratulations!
## HELP, AN ERROR!
Is Keyoxide giving an error when you try to view your profile in the browser? Make sure that you have uploaded your key once using the [upload form](https://keys.openpgp.org/upload) **AND** that you have clicked the link inside the confirmation email: your profile page can't be displayed before this is done.

View file

@ -1,20 +0,0 @@
# Contributing to Keyoxide
Keyoxide is more than this website. It's a project that aims to make cryptography more accessible to everyone. Keyoxide is part of a larger community of people working hard to develop tools that add privacy and security to our digital online lives. Remember: privacy is not a luxury.
## As a developer
As Keyoxide is an open-source project licensed under the permissive [MIT License](https://codeberg.org/keyoxide/web/src/branch/main/LICENSE), everyone is welcome and encouraged to contribute. This can be done in various forms:
* [Open an issue](https://codeberg.org/keyoxide/web/issues) to request changes, new features or simply get help.
* [Open a PR](https://codeberg.org/keyoxide/web/pulls) to directly integrate your own changes and new features.
## Not a developer?
Not a developer? Not a problem? You could:
* Learn more about the importance of online privacy and security and advocate for it (much needed!)
* Write guides for others and help each other out.
* Start using decentralized OpenPGP identity keys.
* Spread the word about Keyoxide and OpenPGP keys in general.
* Talk to persons you know using siloed or closed-source alternatives to Keyoxide.

View file

@ -1,63 +0,0 @@
# Adding a dev.to proof
Let's add a decentralized dev.to proof to your OpenPGP keys.
[[toc]]
## Post a dev.to proof message
Log in to [dev.to](https://dev.to) and create a new post with the following text (make sure to replace FINGERPRINT and USERNAME):
```
This is an OpenPGP proof that connects [my OpenPGP key](https://keyoxide.org/FINGERPRINT) to [this dev.to account](https://dev.to/USERNAME). For details check out https://keyoxide.org/guides/openpgp-proofs
[Verifying my OpenPGP key: openpgp4fpr:FINGERPRINT]
```
After posting, copy the link to the post.
## Update the PGP key
First, edit the key (make sure to replace FINGERPRINT):
```
gpg --edit-key FINGERPRINT
```
Get a list of user IDs and find the index of the one to assign the notation to:
```
list
```
Select the desired user ID (make sure to replace N):
```
uid N
```
Add a new notation:
```
notation
```
Enter the notation (make sure to update with the link to the post copied above):
```
proof@metacode.biz=https://dev.to/USERNAME/POST_TITLE
```
Save the key:
```
save
```
Upload the key to WKD or use the following command to upload the key to [keys.openpgp.org](https://keys.openpgp.org) (make sure to replace FINGERPRINT):
```
gpg --keyserver hkps://keys.openpgp.org --send-keys FINGERPRINT
```
And you're done! Reload your profile page, it should now show a verified dev.to account.

View file

@ -1,63 +0,0 @@
# Adding a Discourse proof
Let's add a decentralized Discourse proof to your OpenPGP keys.
[[toc]]
## Update the Discourse account
Log in to the discourse instance website and add the following text to your **About me** (make sure to replace FINGERPRINT):
```
This is an OpenPGP proof that connects my OpenPGP key to this Discourse account. For details check out https://keyoxide.org/guides/openpgp-proofs
[Verifying my OpenPGP key: openpgp4fpr:FINGERPRINT]
```
After posting, copy the link to your profile page (it should end with your **/u/USERNAME**).
## Update the PGP key
First, edit the key (make sure to replace FINGERPRINT):
```
gpg --edit-key FINGERPRINT
```
Get a list of user IDs and find the index of the one to assign the notation to:
```
list
```
Select the desired user ID (make sure to replace N):
```
uid N
```
Add a new notation:
```
notation
```
Enter the notation (make sure to replace PROFILE_URL with the link to the profile copied above):
```
proof@metacode.biz=PROFILE_URL
```
Save the key:
```
save
```
Upload the key to WKD or use the following command to upload the key to [keys.openpgp.org](https://keys.openpgp.org) (make sure to replace FINGERPRINT):
```
gpg --keyserver hkps://keys.openpgp.org --send-keys FINGERPRINT
```
And you're done! Reload your profile page, it should now show a verified Discourse account.

View file

@ -1,59 +0,0 @@
# Adding a DNS proof
Let's add a decentralized DNS proof to your OpenPGP keys.
[[toc]]
## Update DNS records for your website
Add the following TXT record to the DNS records of the (sub)domain you want to prove control over (make sure to replace FINGERPRINT):
`openpgp4fpr:FINGERPRINT`
No specific TTL value is required.
## Update the PGP key
First, edit the key (make sure to replace FINGERPRINT):
```
gpg --edit-key FINGERPRINT
```
Get a list of user IDs and find the index of the one to assign the notation to:
```
list
```
Select the desired user ID (make sure to replace N):
```
uid N
```
Add a new notation:
```
notation
```
Enter the notation (make sure to replace DOMAIN, don't include https://):
```
proof@metacode.biz=dns:DOMAIN?type=TXT
```
Save the key:
```
save
```
Upload the key to WKD or use the following command to upload the key to [keys.openpgp.org](https://keys.openpgp.org) (make sure to replace FINGERPRINT):
```
gpg --keyserver hkps://keys.openpgp.org --send-keys FINGERPRINT
```
And you're done! Reload your profile page, it should now show a verified domain name.

View file

@ -1,29 +0,0 @@
# Encrypting a message
Let's see how to encrypt a message.
[[toc]]
## Obtain a public key for encryption
The idea is that you use someone's public key to encrypt a message. From then on, the message cannot be decrypted and read by anyone but the person possessing the private keys associated with the public key (they'll have the same fingerprint).
If you already have a public key (or its fingerprint) you would like to use to encrypt a message, great! If not, you could use the following fingerprint:
```
9f0048ac0b23301e1f77e994909f6bd6f80f485d
```
## Encrypt a message
Open the [/encrypt](/encrypt) page and paste the fingerprint in the **Email / key id / fingerprint** field.
Write a message in the **Message** field. Scroll down and press the **ENCRYPT MESSAGE** button.
You have successfully encrypted the message! The encrypted message in the **Message** field can safely be sent via unsecured communication channels knowing that only the person possessing the private key associated with that fingerprint can read it.
## Going further
You could try using different mechanisms of fetching keys, such as **web key directory** or copy-pasting a plaintext public key.
If you'd like to receive PGP encrypted messages, you must first learn the fundamentals of PGP and how to generate and handle your own keypair.

View file

@ -1,41 +0,0 @@
# Feature comparison with Keybase
Let's see how Keyoxide's features compare to those of Keybase.
[[toc]]
## Encrypt and verify
Both Keyoxide and Keybase allow easy encryption of data and verification of signatures. While Keybase can only perform these actions for their users who uploaded at least a public key to their servers, Keyoxide can do this for any key on the internet, whether it's available through web key directory, dedicated key servers or simply copy-pasting a plaintext key.
## Decrypt and sign
Keyoxide cannot decrypt data or sign messages.
Keybase can do both of those things but this should NOT be considered a feature. It requires one to upload their private key to closed-source servers which is an act in stark contradiction with all safety precautions any owner of a private key should aim to heed.
## Online identity proofs
Both Keyoxide and Keybase allow the user to generate proofs of online identity on various platforms. The difference lies in the method of generation and the implications this has on security.
Keybase generates a signed message to be posted by the to-be-verified account. Since this involves a signature, any signing key can be used. If a signing key gets misappropriated, it becomes easy for a bad actor to create fake identity proofs.
Keyoxide uses decentralized OpenPGP proofs in which the identity proofs are stored as notations within the keys themselves. This is only possible when you have access to keys with "certification" capability. As these are the most valuable of keys, they should also be handled more securely than signing keys and are therefore less prone to forgery of identity proofs.
## Social network and additional services
Keybase provides an additional social network, chat functionality, encrypted drive, encrypted git, XLM crypto wallet and much more.
Keyoxide has none of that. Just keys and proofs.
## Openness
Keyoxide is fully open-source. It consists mainly of a client component which is the browser. The supporting server functions are open-source as well.
Keybase has open-source clients but closed-source servers.
## Data safety
Keyoxide lets the user's devices do almost all of the heavy lifting, meaning no data is ever sent to a server to perform any of the actions. Only exceptions to this rule are a couple of "proxy scripts" for proofs that cannot be verified by a browser. These proxy scripts are open-source as well and inspectable by all.
Keybase servers are closed-source. One does not know what happens inside that black box.

View file

@ -1,71 +0,0 @@
# Adding a Gitea proof
Let's add a decentralized Gitea proof to your OpenPGP keys. This will also work on self-hosted instances.
[[toc]]
## Post a Gitea proof message
Log in to a gitea instance like [codeberg.org](https://codeberg.org) and click on **Create new repository**.
Set the repository name to **gitea_proof**.
Set the project description to (make sure to replace FINGERPRINT):
```
[Verifying my OpenPGP key: openpgp4fpr:FINGERPRINT]
```
Optional: edit the README.md to this:
```
This is an OpenPGP proof that connects my OpenPGP key to this Gitea account. For details check out https://keyoxide.org/guides/openpgp-proofs
```
After creating the project, copy the link to the project.
## Update the PGP key
First, edit the key (make sure to replace FINGERPRINT):
```
gpg --edit-key FINGERPRINT
```
Get a list of user IDs and find the index of the one to assign the notation to:
```
list
```
Select the desired user ID (make sure to replace N):
```
uid N
```
Add a new notation:
```
notation
```
Enter the notation (make sure to update with the link to the project copied above):
```
proof@metacode.biz=https://gitea.example.com/USERNAME/gitea_proof
```
Save the key:
```
save
```
Upload the key to WKD or use the following command to upload the key to [keys.openpgp.org](https://keys.openpgp.org) (make sure to replace FINGERPRINT):
```
gpg --keyserver hkps://keys.openpgp.org --send-keys FINGERPRINT
```
And you're done! Reload your profile page, it should now show a verified Gitea account.

View file

@ -1,65 +0,0 @@
# Adding a Github proof
Let's add a decentralized Github proof to your OpenPGP keys.
[[toc]]
## Post a Github proof message
Log in to [github.com](https://github.com) and click on **New gist**.
Name the file **openpgp.md** and copy the following content into it (make sure to replace FINGERPRINT and USERNAME):
```
This is an OpenPGP proof that connects [my OpenPGP key](https://keyoxide.org/FINGERPRINT) to [this Github account](https://github.com/USERNAME). For details check out https://keyoxide.org/guides/openpgp-proofs
[Verifying my OpenPGP key: openpgp4fpr:FINGERPRINT]
```
After creating a public gist, copy the link to the gist.
## Update the PGP key
First, edit the key (make sure to replace FINGERPRINT):
```
gpg --edit-key FINGERPRINT
```
Get a list of user IDs and find the index of the one to assign the notation to:
```
list
```
Select the desired user ID (make sure to replace N):
```
uid N
```
Add a new notation:
```
notation
```
Enter the notation (make sure to update with the link to the post copied above):
```
proof@metacode.biz=https://gist.github.com/USERNAME/12345678912345678912345678912345
```
Save the key:
```
save
```
Upload the key to WKD or use the following command to upload the key to [keys.openpgp.org](https://keys.openpgp.org) (make sure to replace FINGERPRINT):
```
gpg --keyserver hkps://keys.openpgp.org --send-keys FINGERPRINT
```
And you're done! Reload your profile page, it should now show a verified Github account.

View file

@ -1,73 +0,0 @@
# Adding a GitLab proof
Let's add a decentralized GitLab proof to your OpenPGP keys. This will also work on self-hosted instances.
[[toc]]
## Post a GitLab proof message
Log in to [gitlab.com](https://gitlab.com) or any other GitLab instance (your profile must be "public", not "private") and click on **New project**.
Set the project name to a name of your choosing.
Set the project slug to **gitlab_proof**.
Set the project description to (make sure to replace FINGERPRINT):
```
[Verifying my OpenPGP key: openpgp4fpr:FINGERPRINT]
```
Optional: edit the README.md to this:
```
This is an OpenPGP proof that connects my OpenPGP key to this GitLab account. For details check out https://keyoxide.org/guides/openpgp-proofs
```
After creating the project, copy the link to the project.
## Update the PGP key
First, edit the key (make sure to replace FINGERPRINT):
```
gpg --edit-key FINGERPRINT
```
Get a list of user IDs and find the index of the one to assign the notation to:
```
list
```
Select the desired user ID (make sure to replace N):
```
uid N
```
Add a new notation:
```
notation
```
Enter the notation (make sure to update with the link to the project copied above):
```
proof@metacode.biz=https://gitlab.example.com/USERNAME/gitlab_proof
```
Save the key:
```
save
```
Upload the key to WKD or use the following command to upload the key to [keys.openpgp.org](https://keys.openpgp.org) (make sure to replace FINGERPRINT):
```
gpg --keyserver hkps://keys.openpgp.org --send-keys FINGERPRINT
```
And you're done! Reload your profile page, it should now show a verified GitLab account.

View file

@ -1,63 +0,0 @@
# Adding a Hackernews proof
Let's add a decentralized Hackernews proof to your OpenPGP keys.
[[toc]]
## Update the Hackernews account
Log in to [Hackernews](https://news.ycombinator.com) and click on your **username**.
Add the following lines to your **about** (make sure to replace FINGERPRINT):
```
This is an OpenPGP proof that connects my OpenPGP key to this Hackernews account. For details check out https://keyoxide.org/guides/openpgp-proofs
[Verifying my OpenPGP key: openpgp4fpr:FINGERPRINT]
```
## Update the PGP key
First, edit the key (make sure to replace FINGERPRINT):
```
gpg --edit-key FINGERPRINT
```
Get a list of user IDs and find the index of the one to assign the notation to:
```
list
```
Select the desired user ID (make sure to replace N):
```
uid N
```
Add a new notation:
```
notation
```
Enter the notation (make sure to replace USERNAME):
```
proof@metacode.biz=https://news.ycombinator.com/user?id=USERNAME
```
Save the key:
```
save
```
Upload the key to WKD or use the following command to upload the key to [keys.openpgp.org](https://keys.openpgp.org) (make sure to replace FINGERPRINT):
```
gpg --keyserver hkps://keys.openpgp.org --send-keys FINGERPRINT
```
And you're done! Reload your profile page, it should now show a verified Hackernews account.

View file

@ -1,79 +0,0 @@
# Adding an IRC proof
Let's add a decentralized IRC proof to your OpenPGP keys.
[[toc]]
### Add a property to your IRC taxonomy
After logging in into the IRC server with your registered nickname, send the
following message (make sure to replace FINGERPRINT):
```
/msg NickServ SET PROPERTY KEY openpgp4fpr:FINGERPRINT
```
To check whether successful, send (make sure to replace NICK):
```
/msg NickServ TAXONOMY NICK
```
To add more fingerprints, send:
```
/msg NickServ SET PROPERTY KEY2 openpgp4fpr:FINGERPRINT
```
### Update the PGP key
First, edit the key (make sure to replace FINGERPRINT):
```
gpg --edit-key FINGERPRINT
```
Get a list of user IDs and find the index of the one to assign the notation to:
```
list
```
Select the desired user ID (make sure to replace N):
```
uid N
```
Add a new notation:
```
notation
```
Enter the notation (make sure to replace IRC_SERVER and NICK):
```
proof@metacode.biz=irc://IRC_SERVER/NICK
```
So, for user `foo` on the freenode server, this would be:
```
proof@metacode.biz=irc://chat.freenode.net/foo
```
Save the key:
```
save
```
Upload the key to WKD or use the following command to upload the key to
[keys.openpgp.org](https://keys.openpgp.org) (make sure to replace FINGERPRINT):
```
gpg --keyserver hkps://keys.openpgp.org --send-keys FINGERPRINT
```
And you're done! Reload your profile page, it should now show an IRC account.

View file

@ -1,61 +0,0 @@
# Adding a Lobste.rs proof
Let's add a decentralized Lobste.rs proof to your OpenPGP keys.
[[toc]]
## Update the Lobste.rs account
Log in to [Lobste.rs](https://lobste.rs) and append the following text to the **About** section (make sure to replace FINGERPRINT):
```
This is an OpenPGP proof that connects my OpenPGP key to this Lobste.rs account. For details check out https://keyoxide.org/guides/openpgp-proofs
[Verifying my OpenPGP key: openpgp4fpr:FINGERPRINT]
```
## Update the PGP key
First, edit the key (make sure to replace FINGERPRINT):
```
gpg --edit-key FINGERPRINT
```
Get a list of user IDs and find the index of the one to assign the notation to:
```
list
```
Select the desired user ID (make sure to replace N):
```
uid N
```
Add a new notation:
```
notation
```
Enter the notation (make sure to replace USERNAME):
```
proof@metacode.biz=https://lobste.rs/u/USERNAME
```
Save the key:
```
save
```
Upload the key to WKD or use the following command to upload the key to [keys.openpgp.org](https://keys.openpgp.org) (make sure to replace FINGERPRINT):
```
gpg --keyserver hkps://keys.openpgp.org --send-keys FINGERPRINT
```
And you're done! Reload your profile page, it should now show a verified Lobste.rs account.

View file

@ -1,63 +0,0 @@
# Deleting Proofs using GnuPG
Over time, you may need to delete proofs. Changing proofs can be achieved by deleting proofs and adding new ones.
## Delete all proofs
First, edit the key (make sure to replace FINGERPRINT):
```
gpg --edit-key FINGERPRINT
```
Launch the notation prompt:
```
notation
```
Enter the 'none' notation to delete all notations:
```
none
```
Save the changes:
```
save
```
## Delete one of your proofs
First, edit the key (make sure to replace FINGERPRINT):
```
gpg --edit-key FINGERPRINT
```
Launch the notation prompt:
```
notation
```
Enter the **-** (minus) symbol followed by the proof you want to delete. Make sure you type the proof exactly like it is in your key.
```
-proof@metacode.biz=dns:yourdomain.org?type=TXT
```
_To make it easier to enter the right proof, you could first [list all proofs](managing-proofs-listing) and simply copy the proof (including "proof@metacode.biz=") you want to delete._
Save the changes:
```
save
```
Upload the key to WKD or use the following command to upload the key to [keys.openpgp.org](https://keys.openpgp.org) (make sure to replace FINGERPRINT):
```
gpg --keyserver hkps://keys.openpgp.org --send-keys FINGERPRINT
```

View file

@ -1,35 +0,0 @@
# Listing Proofs using GnuPG
Let's list the identity proofs stored in our OpenPGP keys.
## Listing notations in GnuPG
First, edit the key (make sure to replace FINGERPRINT):
```
gpg --edit-key FINGERPRINT
```
List detailed preferences:
```
showpref
```
You should now see your key details, uid, and proofs assigned to your keys:
```
[ultimate] (1). Your Name <your@email>
Cipher: AES256, AES192, AES, 3DES
Digest: SHA512, SHA384, SHA256, SHA1
Compression: ZLIB, BZIP2, ZIP, Uncompressed
Features: MDC, Keyserver no-modify
Notations: proof@metacode.biz=https://gist.github.com/youruser/somehash
proof@metacode.biz=dns:yourdomain.org?type=TXT</your@email>
```
Exit gpg:
```
quit
```

View file

@ -1,57 +0,0 @@
# Adding a Mastodon proof
Let's add a decentralized Mastodon proof to your OpenPGP keys.
[[toc]]
## Update the Mastodon account
Log in to your Mastodon instance and click on **Edit profile**.
Add a new item under **Profile metadata** with the label **OpenPGP** and your PGP fingerprint as the content, or with the label **Keyoxide** and your Keyoxide profile URL as the content.
## Update the PGP key
First, edit the key (make sure to replace FINGERPRINT):
```
gpg --edit-key FINGERPRINT
```
Get a list of user IDs and find the index of the one to assign the notation to:
```
list
```
Select the desired user ID (make sure to replace N):
```
uid N
```
Add a new notation:
```
notation
```
Enter the notation (make sure to update the link):
```
proof@metacode.biz=https://INSTANCE.ORG/@USERNAME
```
Save the key:
```
save
```
Upload the key to WKD or use the following command to upload the key to [keys.openpgp.org](https://keys.openpgp.org) (make sure to replace FINGERPRINT):
```
gpg --keyserver hkps://keys.openpgp.org --send-keys FINGERPRINT
```
And you're done! Reload your profile page, it should now show a verified Mastodon account.

View file

@ -1,81 +0,0 @@
# Adding a Matrix proof
Let's add a decentralized Matrix proof to your OpenPGP keys.
[[toc]]
### Sending a proof message
After logging in into Matrix, join the
[#doipver:matrix.org](https://matrix.to/#/#doipver:matrix.org) room and send the
following message (make sure to replace FINGERPRINT)
```
[Verifying my OpenPGP key: openpgp4fpr:FINGERPRINT]
```
Click on "View Source" for that message, you should now see the value for
`room_id` and `event_id`.
The value for `room_id` should be `!dBfQZxCoGVmSTujfiv:matrix.org`. The value
for `event_id` is unique to your message.
If your Matrix client does not support "View Source", choose "Share" or
"Permalink". The URL obtained should look like this:
```
https://matrix.to/#/ROOM_ID/EVENT_ID?via=...
```
### Update the PGP key
First, edit the key (make sure to replace FINGERPRINT):
```
gpg --edit-key FINGERPRINT
```
Get a list of user IDs and find the index of the one to assign the notation to:
```
list
```
Select the desired user ID (make sure to replace N):
```
uid N
```
Add a new notation:
```
notation
```
Enter the notation (make sure to replace USER_ID, ROOM_ID, EVENT_ID):
```
proof@metacode.biz=matrix:u/USER_ID?org.keyoxide.r=ROOM_ID&org.keyoxide.e=EVENT_ID
```
So, for user `@foo:matrix.org`, this would be:
```
proof@metacode.biz=matrix:u/@foo:matrix.org?org.keyoxide.r=!dBfQZxCoGVmSTujfiv:matrix.org&org.keyoxide.e=$3dVX1nv3lmwnKxc0mgto_Sf-REVr45Z6G7LWLWal10w
```
Save the key:
```
save
```
Upload the key to WKD or use the following command to upload the key to
[keys.openpgp.org](https://keys.openpgp.org) (make sure to replace FINGERPRINT):
```
gpg --keyserver hkps://keys.openpgp.org --send-keys FINGERPRINT
```
And you're done! Reload your profile page, it should now show a Matrix account.

View file

@ -1,25 +0,0 @@
# Migrating from Keybase
Let's see how easy it is to get a Keyoxide profile when you already have a Keybase account.
[[toc]]
## Claim your Keyoxide profile
Go to the [profile URL generator](/util/profile-url), set Keybase as Source and follow the Keybase specific instructions. Has a profile URL been generated? Congratulations, you now have your very own Keyoxide profile!
## Actually migrating to Keyoxide
Unfortunately, you get very little control when using your Keybase key directly. You will need to generate your own PGP keypair (use guides like [this one](https://spin.atomicobject.com/2013/11/24/secure-gpg-keys-guide/) for help) to unlock the full potential of [distributed identity proofs](/guides/proofs).
Have you generated a keypair and made the public key accessible through [web key directory (WKD)](/guides/web-key-directory) or uploaded it to [keys.openpgp.org](https://keys.openpgp.org/)? Use the [profile URL generator](/util/profile-url) to get your own profile URL and [start adding identity proofs](/guides).
## Keyoxide as a partial replacement for Keybase
It's important to moderate expectations and state that [Keyoxide](/) only replaces the subset of Keybase features that are considered the "core" features: message encryption, signature verification and identity proofs.
Message decryption and signing are **not** supported features: they would require you to upload your secret key to a website which is a big **no-no**.
Encrypted chat and cloud storage are **not** supported features: there are plenty of dedicated alternative services.
If you need any of these Keybase-specific supports, [Keyoxide](/) may not be a full Keybase replacement for you but you could still generate a profile and take advantage of **distributed identity proofs**.

View file

@ -1,35 +0,0 @@
# How OpenPGP identity proofs work
[[toc]]
## Decentralized OpenPGP identity proofs
Decentralized OpenPGP identity proofs are the brainchild of Wiktor who wrote the original guide on [his website](https://metacode.biz/openpgp/proofs) (a suggested read to get first-hand information).
Unlike proofs provided by for example [Keybase](https://keybase.io), OpenPGP proofs are stored inside the PGP keys themselves instead of being mere signatures. Since this operation requires keys with "certify" capabilities and not simply "sign" capabilities, these OpenPGP proofs could be considered more secure.
## Example
* Alice and Bob have been talking for years on service A. Alice already has an account on service B. Bob wants to move to service B as well. A simple decentralized proof confirms that the person who is known as Alice on service A is also known as Alice on service B. Bob can safely move to service B and talk to Alice without having to meet in person to confirm their accounts.
* Alice has received a friend request from Bob29 on service C. Is this the same Bob from service A or not? A simple decentralized proof confirms that the person who is known as Bob on platform A is also known as Bob29 on service C. Turns out 28 Bobs were already using service C.
* Bob has been invited by an account named Alyce to create an account on an unknown server. Is this a legit request? A simple decentralized proof tells Bob that Alice does not have such an account. Bob knows something is up and does not click the link possibly sent by an imposter.
## What an OpenPGP proof looks like
Every OpenPGP identity proof is stored in the PGP key as a notation that looks like this:
`proof@metacode.biz=https://twitter.com/USERNAME/status/1234567891234567891`
This particular proof is for a Twitter account (read more in the [Twitter guide](/guides/twitter)). Let's analyse the notation:
* **proof** means the current notation is for an identity proof.
* **@metacode.biz** is the domain of the person who came up with OpenPGP proofs and serves as a namespace for the notation. The domain is included and used for all proofs to comply with the [OpenPGP Message Format standard (RFC 4880)](https://tools.ietf.org/html/rfc4880#section-5.2.3.16).
* **https://twitter.com/USERNAME/status/1234567891234567891** is the value of the notation. It is a link to the piece of online content that contains a pre-defined message which must always include the fingerprint of the PGP key that will hold the proof.
The proof should always link to a document that can be parsed as JSON to make the verification easy and feasible by the browser. Sometimes however, due to CORS restrictions or API requirements (as is the case for Twitter), no such link is provided by the platform. In these rare exceptional cases, the verification process is delegated to the Keyoxide server which will communicate directly with the platform's servers to get the content of the post.
## Your turn
If you'd like to add decentralized OpenPGP identity proofs to your key, go to the [guides](/guides) and find the right one for your platform of choice. You may find the process to be remarkably easy.
If your platform is not in the list of [guides](/guides), it's not supported yet. See the [contributing guide](/guides/contributing) for more information on how to get that platform supported.

View file

@ -1,67 +0,0 @@
# Adding an Owncast proof
Let's add a decentralized Owncast proof to your OpenPGP keys.
[[toc]]
## Update your Owncast server configuration
On your server, add the following lines to the `instanceDetails > socialHandles` entry in the `config.yaml` (make sure to replace FINGERPRINT):
```
- platform: keyoxide
url: https://keyoxide.org/FINGERPRINT
```
When not identifying your key by its fingerprint (for example, when using WKD), add the following lines instead:
```
- platform: keyoxide
url: https://keyoxide.org/EMAIL#FINGERPRINT
```
## Update the PGP key
First, edit the key (make sure to replace FINGERPRINT):
```
gpg --edit-key FINGERPRINT
```
Get a list of user IDs and find the index of the one to assign the notation to:
```
list
```
Select the desired user ID (make sure to replace N):
```
uid N
```
Add a new notation:
```
notation
```
Enter the notation (make sure to update with the domain of the Owncast instance):
```
proof@metacode.biz=https://stream.example.org
```
Save the key:
```
save
```
Upload the key to WKD or use the following command to upload the key to [keys.openpgp.org](https://keys.openpgp.org) (make sure to replace FINGERPRINT):
```
gpg --keyserver hkps://keys.openpgp.org --send-keys FINGERPRINT
```
And you're done! Reload your profile page, it should now show a verified Owncast account.

View file

@ -1,63 +0,0 @@
# Adding a Pixelfed proof
Let's add a decentralized Pixelfed proof to your OpenPGP keys.
[[toc]]
## Update the Pixelfed account
Log in to your Pixelfed instance and add the following lines to your **Bio** (make sure to replace FINGERPRINT):
```
This is an OpenPGP proof that connects my OpenPGP key to this Pixelfed account. For details check out https://keyoxide.org/guides/openpgp-proofs
[Verifying my OpenPGP key: openpgp4fpr:FINGERPRINT]
```
## Update the PGP key
First, edit the key (make sure to replace FINGERPRINT):
```
gpg --edit-key FINGERPRINT
```
Get a list of user IDs and find the index of the one to assign the notation to:
```
list
```
Select the desired user ID (make sure to replace N):
```
uid N
```
Add a new notation:
```
notation
```
Enter the notation (make sure to update the link):
```
proof@metacode.biz=https://INSTANCE.ORG/users/USERNAME
```
Please note that the **/users/** part of the URL is mandatory for the proof to work.
Save the key:
```
save
```
Upload the key to WKD or use the following command to upload the key to [keys.openpgp.org](https://keys.openpgp.org) (make sure to replace FINGERPRINT):
```
gpg --keyserver hkps://keys.openpgp.org --send-keys FINGERPRINT
```
And you're done! Reload your profile page, it should now show a verified Fediverse account (Pixelfed is part of the [Fediverse](#https://en.wikipedia.org/wiki/Fediverse)).

View file

@ -1,63 +0,0 @@
# Adding a Pleroma proof
Let's add a decentralized Pleroma proof to your OpenPGP keys.
[[toc]]
## Update the Pleroma account
Log in to your Pleroma instance and add the following lines to your **Bio** (make sure to replace FINGERPRINT):
```
This is an OpenPGP proof that connects my OpenPGP key to this Pleroma account. For details check out https://keyoxide.org/guides/openpgp-proofs
[Verifying my OpenPGP key: openpgp4fpr:FINGERPRINT]
```
## Update the PGP key
First, edit the key (make sure to replace FINGERPRINT):
```
gpg --edit-key FINGERPRINT
```
Get a list of user IDs and find the index of the one to assign the notation to:
```
list
```
Select the desired user ID (make sure to replace N):
```
uid N
```
Add a new notation:
```
notation
```
Enter the notation (make sure to update the link):
```
proof@metacode.biz=https://INSTANCE.ORG/users/USERNAME
```
Please note that the **/users/** part of the URL is mandatory for the proof to work.
Save the key:
```
save
```
Upload the key to WKD or use the following command to upload the key to [keys.openpgp.org](https://keys.openpgp.org) (make sure to replace FINGERPRINT):
```
gpg --keyserver hkps://keys.openpgp.org --send-keys FINGERPRINT
```
And you're done! Reload your profile page, it should now show a verified Fediverse account (Pleroma is part of the [Fediverse](#https://en.wikipedia.org/wiki/Fediverse)).

View file

@ -1,29 +0,0 @@
# Verifying identity proofs
Let's see how to verify identity proofs.
[[toc]]
## Obtain a public key for verification
The idea is that anyone can add identity proofs of various platforms in their keys. Since this information is kept in the public key, you could take anyone's public key and check whether they indeed have control over the accounts they claim to.
If you already have a public key (or its fingerprint) with OpenPGP identity proofs you would like to use to verify, great! If not, you could use the following fingerprint:
`9f0048ac0b23301e1f77e994909f6bd6f80f485d`
## Verify proofs
Open the [keyoxide.org/proofs](/proofs) page and paste the fingerprint in the **Email / key id / fingerprint** field. Scroll down and press the **VERIFY PROOFS** button.
You now see a list of domains and/or accounts on platforms for which the owner of the public key claims to have an control over.
If the last link on a line says **proof**, the proof could not be verified for any number of reasons but Keyoxide still allows to check the supposed proof and decide for yourself whether you trust the claim. If the
If the last link on a line says **verified**, the owner of the public key indeed has shown beyond doubt that it has control over the domain or account.
## Your turn
If you'd like to add decentralized OpenPGP identity proofs to your key, go to the [guides](/guides) and find the right one for your platform of choice. You may find the process to be remarkably easy.
If your platform is not in the list of [guides](/guides), it's not supported yet. See the [contributing guide](/guides/contributing) for more information on how to get that platform supported.

View file

@ -1,63 +0,0 @@
# Adding a Reddit proof
Let's add a decentralized Reddit proof to your OpenPGP keys.
[[toc]]
## Post a Reddit proof message
Log in to [www.reddit.com](https://www.reddit.com) and create a new post with the following text (make sure to replace FINGERPRINT):
```
This is an OpenPGP proof that connects my OpenPGP key to this Reddit account. For details check out https://keyoxide.org/guides/openpgp-proofs
[Verifying my OpenPGP key: openpgp4fpr:FINGERPRINT]
```
After posting, copy the link to the post.
## Update the PGP key
First, edit the key (make sure to replace FINGERPRINT):
```
gpg --edit-key FINGERPRINT
```
Get a list of user IDs and find the index of the one to assign the notation to:
```
list
```
Select the desired user ID (make sure to replace N):
```
uid N
```
Add a new notation:
```
notation
```
Enter the notation (make sure to update with the link to the post copied above):
```
proof@metacode.biz=https://www.reddit.com/user/USERNAME/comments/123123/TITLE/
```
Save the key:
```
save
```
Upload the key to WKD or use the following command to upload the key to [keys.openpgp.org](https://keys.openpgp.org) (make sure to replace FINGERPRINT):
```
gpg --keyserver hkps://keys.openpgp.org --send-keys FINGERPRINT
```
And you're done! Reload your profile page, it should now show a verified Reddit account.

View file

@ -1,30 +0,0 @@
# Self-hosting Keyoxide
Self-hosting Keyoxide is an important aspect of the project. Users need to trust the Keyoxide instance they're using to reliably verify identities. Making Keyoxide itself decentralized means no one needs to trust a central server. If a friend or family member is hosting a Keyoxide instance, it becomes much easier to trust the instance!
## Docker
- Run `docker run -d -p 3000:3000 keyoxide/keyoxide:stable`
### Configuration
- Add environment variables to the docker command:
`docker run -d -p 3000:3000 -e PROXY_HOSTNAME=proxy.domain.tld keyoxide/keyoxide:stable`
## Without Docker
- Fetch the [source code](https://codeberg.org/keyoxide/web) and put the files on your server
- Run `yarn` or `npm install` to install the dependencies
- Run `yarn run start` or `npm run start` to start the server at `http://localhost:3000`
- Point your reverse proxy to `http://localhost:3000`
### Configuration
- Add a `.env` file to the root directory of the source code:
```
# .env file
# Enable the use of a proxy (replace with your proxy server domain)
PROXY_HOSTNAME=proxy.domain.tld
```

View file

@ -1,13 +0,0 @@
# Are you a service provider?
If you have:
* a website that allows users to create accounts
* a messaging platform
* any other type of service that may require users to prove their online identity
Then you may be interested in supporting decentralized identity proofs as they allow your users to securely prove their identity across services. Take a look at this [example](guides/service-provider) to find out how two persons can gain more confidence in knowing they are talking to and interacting with the right person in an online world where impersonating is all too easy.
The internet could be a slightly safer place if your service allowed your users to prove their identity. All the service needs to do is make a JSON file available with basic details about the user and set the correct CORS headers.
The [documentation](https://github.com/wiktor-k/openpgp-proofs#for-service-providers) on what is precisely required is provided by the original creator of decentralized OpenPGP identity proofs.

View file

@ -1,94 +0,0 @@
# Creating signature profiles
Let's create a signature profile. This is a profile that can be verified by Keyoxide but the data for which lives in a clear-signed text document rather than as notations in the key itself.
[[toc]]
## Why put claims in a signed document/signature profile?
Storing claims inside the key as notations is a powerful method. Wherever the public key goes, so go the identity claims. This allows one to use the existing vast network of key sharing tools to also share these identity claims.
There are drawbacks to this: you lose granularity. You cannot pick and choose the claims you want to send to certain people or use for certain purposes. There is also the possibility that notations in keys could be scraped as the keys are publicly available.
Putting (certain) claims in a signature profile solves both drawbacks. You can choose which claims to be associated with each other and you can choose which persons can see this by only sending it to them. You can even encrypt the signature profile! Since the signature profile is not publicly available (unless you make it so), there is no possibility to scrape the contents of it.
Note that there is one catch: the person you send it to could publish it. Only send claims you wish to keep secret to people you trust!
## Writing the plaintext document
Using terminal tools like vim, emacs, nano or graphical tools like notepad, create a new document. The content should eventually look like this:
```
Hey there! Here's a signature profile with proofs related to the DOIP project (https://doip.rocks).
Verify this profile at https://keyoxide.org/sig
proof=dns:doip.rocks
proof=https://fosstodon.org/@keyoxide
```
You can add as much "regular" text as you'd like. The point of these signature profiles is that they are both human-friendly and machine-readable. In this case, the first line is meant for humans.
The second thing to add is a link to a website that can verify these signature profiles. If you know or host a different instance, you can choose to link that instance instead! If not, you are welcome to leave the link as is. Note that this link is not mandatory but could prove very helpful to the recipients.
Finally, you can add proofs by adding a new line beginning with **proof=** followed by the claim that is given by the [guides](/guides). So, for example, **proof=dns:doip.rocks** verifies a domain name and **proof@metacode.biz=https://twitter.com/USERNAME/status/1234567891234567891** verifies a Twitter account.
You can add as many claims as you wish as long as each is on their own line.
## Signing the document
You will now sign this document, making it untemperable and possible to prove beyond doubt that you, as holder of the private key, and only you could have signed the document.
Assuming you have an OpenPGP key with signing capabilities, execute the following command in the terminal:
```
gpg -u EMAIL_ADDRESS --clear-sign FILENAME
```
Replace EMAIL_ADDRESS and FILENAME with the correct values. As an example:
```
gpg -u test@doip.rocks --clear-sign sigpro.txt
```
This will generate a file named **sigpro.txt.asc** with the following content:
```
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA512
Hey there! Here's a signature profile with proofs related to the DOIP project (https://doip.rocks).
Verify this profile at https://keyoxide.org/sig
proof=dns:doip.rocks
proof=https://fosstodon.org/@keyoxide
-----BEGIN PGP SIGNATURE-----
iQHEBAEBCgAuFiEENjcgJSPnwTCat56Z7y3FgntEX0sFAl/7L0MQHHRlc3RAZG9p
cC5yb2NrcwAKCRDvLcWCe0RfS3iYC/0QQqz2lzSNrkApdIN9OJFfd/sP2qeGr/uH
98YHa+ucwBxer6yrAaTYYuBJg1uyzdxQhqF2jWno7FwN4crnj15AN5XGemjpmqat
py9wG6vCVjC81q/BWMIMZ7RJ/m8F8Kz556xHiU8KbqLNDqFVcT35/PhJsw71XVCI
N3HgrgD7CY/vIsZ3WIH7mne3q9O7X4TJQtFoZZ/l9lKj7qk3LrSFnL6q+JxUr2Im
xfYZKaSz6lmLf+vfPc59JuQtV1z0HSNDQkpKEjmLeIlc+ZNAdSQRjkfi+UDK7eKV
KGOlkcslroJO6rT3ruqx9L3hHtrM8dKQFgtRSaofB51HCyhNzmipbBHnLnKQrcf6
o8nn9OkP7F9NfbBE6xYIUCkgnv1lQbzeXsLLVuEKMW8bvZOmI7jTcthqnwzEIHj/
G4p+zPGgO+6Pzuhn47fxH+QZ0KPA8o2vx0DvOkZT6HEqG+EqpIoC/a7wD68n789c
K2NLCVb9oIGarPfhIdPV3QbrA5eXRRQ=
=QyNy
-----END PGP SIGNATURE-----
```
This document is a fully functional signature profile! Test it out [here](/sig).
### The process of fetching keys
Keyoxide verifies the validity of the signature before verifying the individual claims. To this end, it needs to find the key that signed this profile.
Keyoxide always first checks whether it can fetch the public key using [Web Key Directory](/guides/web-key-directory) with the email address provided as **sender**.
If this fails, Keyoxide tries to fetch the key using a keyserver. By default, it will use [keys.openpgp.org](https://keys.openpgp.org) (which tends to be the most reliable of keyservers). To set your preferred keyserver, execute the following command instead:
```
gpg -u EMAIL_ADDRESS --sig-keyserver-url https://KEYSERVER_DOMAIN/ --clear-sign FILENAME
```

View file

@ -1,63 +0,0 @@
# Adding a Twitter proof
Let's add a decentralized Twitter proof to your OpenPGP keys.
[[toc]]
## Post a Twitter proof message
Log in to [twitter.com](https://twitter.com) and compose a new tweet with the following text (make sure to replace FINGERPRINT):
```
This is an OpenPGP proof that connects my OpenPGP key to this Twitter account. For details check out https://keyoxide.org/guides/openpgp-proofs
[Verifying my OpenPGP key: openpgp4fpr:FINGERPRINT]
```
After posting, copy the link to the tweet.
## Update the PGP key
First, edit the key (make sure to replace FINGERPRINT):
```
gpg --edit-key FINGERPRINT
```
Get a list of user IDs and find the index of the one to assign the notation to:
```
list
```
Select the desired user ID (make sure to replace N):
```
uid N
```
Add a new notation:
```
notation
```
Enter the notation (make sure to update with the link to the tweet copied above):
```
proof@metacode.biz=https://twitter.com/USERNAME/status/1234567891234567891
```
Save the key:
```
save
```
Upload the key to WKD or use the following command to upload the key to [keys.openpgp.org](https://keys.openpgp.org) (make sure to replace FINGERPRINT):
```
gpg --keyserver hkps://keys.openpgp.org --send-keys FINGERPRINT
```
And you're done! Reload your profile page, it should now show a verified Twitter account.

View file

@ -1,67 +0,0 @@
# Verifying a signature
Let's see how to verify an OpenPGP signature.
[[toc]]
## Obtain a signature
If you already have a signature you would like to verify, great! If not, let's use the following signature for the guide:
```
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256
I like pineapple.
-----BEGIN PGP SIGNATURE-----
iQJDBAEBCAAtFiEEog/Pt4tEmnyVrrtlNzZ/SvQIetEFAl70mVUPHHlhcm1vQHlh
cm1vLmV1AAoJEDc2f0r0CHrRQXIP/08uza9zOtmZXv5K+uPGVzDKwkgPgZJEezX7
6iQ358f1pjSRvYfQ5aB13k2epUHoqCKArMYu1zPqxhvLvvAvp8uOHABnr9NGL3El
u7UUgaeUNHkr0gxCKEq3p81abrrbbWveP8OBP4RyxmaFx13Xcj7mfDluiBHmjVvv
WU09EdH9VPlJ7WfZ+2G2ZZDHuE5XiaeP7ocugTxXXLkp33zwpDX0+ZuCIXM6fQGe
OccSffglFPdNBnfasuuxDWxTQPsEbWGOPJV+CAPmBDeApX+TBF9bovO3hw4Uozk2
VT7EAy8Hb0SOrUb3UNGxzoKv++5676IxyB4JXX0Tr9O4ZxhO8o9pEEHwirtn/J1+
MWven4gVlWM/6bMeUqx6ydyNc2nqF5059yfRmwGMlp09x82G4x1bcf6aDZ+5njDG
fS5T2OpXRIkZHJx8BhmZjsxiDR0KV44zwHpt06+96ef3EDWB0BcP6M+a5Rtc33zf
irRmQd2M6RLyXCYtdGIiiAFRuomw802U4F0P4LwVrZdbGA6ObqBv1k8BUFCMbMz8
Ab4hF7kO4z0Vh3JaKzcHey0pOzdNCPpAHZ51sAoAnFDM4PdMBgQxxVweCMu4KYMZ
FN8sNn42oY/b7gDmwCelVhgD+rvUn/a8+B7CDmCp+wIquyrjrTt00voATcb+ZPMJ
pTXJ/NcM
=rqTX
-----END PGP SIGNATURE-----
```
Copy the above signature.
## Verify the signature
Open the [/verify](/verify) page and paste the signature in the corresponding field. Scroll down and press the **VERIFY SIGNATURE** button.
Keyoxide lets you know the signature was verified and signed by a certain person.
## Verify the signature against a specific public key
Sometimes, you want to know if a specific person or public key was used to create a signature. In this case, let's figure out if the message was signed by Yarmo's public key or his friend Wiktor's public key.
Copy the following fingerprint:
```
653909A2F0E37C106F5FAF546C8857E0D8E8F074
```
Paste it in the **Email / key id / fingerprint** field under **Public Key (3: HKP server)** and press the big button again. It could not be verified. Guess it wasn't Wiktor who signed that message.
Now, copy the following fingerprint:
```
9f0048ac0b23301e1f77e994909f6bd6f80f485d
```
Paste it in the same field and press the big button again. It did verify! It was Yarmo all along.
## Going further
You could try using different mechanisms of fetching keys, such as **web key directory** or copy-pasting a plaintext public key.
If you'd like to sign messages using PGP, you must first learn the fundamentals of PGP and how to generate and handle your own keypair.

View file

@ -1,47 +0,0 @@
# Uploading keys using web key directory
[[toc]]
## Web key directory
[Web key directory](https://datatracker.ietf.org/doc/draft-koch-openpgp-webkey-service/) or WKD refers to the method of uploading one's public key to their website in a specific location to make it easily accessible by other services supporting WKD. The key will be discoverable using an identifier similar to an email address: **username@domain.org**.
The benefit of WKD is having full control over the key while still having it widely available. It does however require a domain and some form of file hosting. Luckily, [openpgp.org](https://keys.openpgp.org/about/usage#wkd-as-a-service) have made a WKD-as-a-service. Read more at the end of the guide.
It exists in two variants: the Direct setup and the Advanced setup. Despite their names, both require roughly the same steps.
## The Direct setup
To make your keys available via WKD using the Direct setup, you'll need two paths on your server:
**https://domain.org/.well-known/openpgpkey/policy**: this is an empty file
**https://domain.org/.well-known/openpgpkey/hu/LOCALPART**: this is the binary public key (so NOT ASCII armored)
The LOCALPART above is actually the username hashed using the SHA-1 algorithm and encoded using the Z-Base-32 method. As it's not humanly possible to compute this by ourselves, Keyoxide provides a [small utility to do this for you](/util/wkd).
So if you wish to make your key available as **jimothy@dm.com**, according to the [small utility](/util/wkd), the URL would become:
```
https://dm.com/.well-known/openpgpkey/hu/n9utc41qty791upt63rm5xtiudabmw6m
```
## The Advanced setup
While not necessary if the Direct setup works, there is a second setup to make WKD work: the Advanced setup. The paths needed are:
**https://openpgpkey.domain.org/.well-known/openpgpkey/domain.org/policy**: this is an empty file
**https://openpgpkey.domain.org/.well-known/openpgpkey/domain.org/hu/LOCALPART**: this is the binary public key (so NOT ASCII armored)
Indeed, quite similar to the Direct setup, except for the **openpgpkey** subdomain and the additional **domain.org** in the path of the public key.
The public key for **jimothy@dm.com** would be available at:
```
https://openpgpkey.dm.com/.well-known/openpgpkey/hu/dm.com/n9utc41qty791upt63rm5xtiudabmw6m
```
## WKD-as-a-service
In case hosting is problem, Openpgp.org has a handy [WKD-as-a-service](https://keys.openpgp.org/about/usage#wkd-as-a-service).

View file

@ -1,81 +0,0 @@
# Adding a XMPP proof
Let's add a decentralized XMPP proof to your OpenPGP keys.
[[toc]]
### Add a message to your XMPP vCard
Go to (mov.im)[https://mov.im] and log in using your XMPP credentials. Click on **Configuration** and append the following message to the **About Me** section (make sure to replace FINGERPRINT):
```
This is an OpenPGP proof that connects my OpenPGP key to this XMPP account. For details check out https://keyoxide.org/guides/openpgp-proofs
[Verifying my OpenPGP key: openpgp4fpr:FINGERPRINT]
```
Using native XMPP clients that support editing the vCard data (such as [Gajim](https://gajim.org/)) should work as well. Unfortunately, this method appears unreliable and does not work for some.
### Update the PGP key (basic edition)
First, edit the key (make sure to replace FINGERPRINT):
```
gpg --edit-key FINGERPRINT
```
Get a list of user IDs and find the index of the one to assign the notation to:
```
list
```
Select the desired user ID (make sure to replace N):
```
uid N
```
Add a new notation:
```
notation
```
Enter the notation (make sure to replace XMPP-ID):
```
proof@metacode.biz=xmpp:XMPP-ID
```
The XMPP-ID looks something like an email address: **user@domain.org**.
Save the key:
```
save
```
Upload the key to WKD or use the following command to upload the key to [keys.openpgp.org](https://keys.openpgp.org) (make sure to replace FINGERPRINT):
```
gpg --keyserver hkps://keys.openpgp.org --send-keys FINGERPRINT
```
And you're done! Reload your profile page, it should now show a XMPP account.
### Update the PGP key (OMEMO edition)
XMPP communication can be end-to-end encrypted with [OMEMO](https://conversations.im/omemo/). Verifying OMEMO fingerprints is essential to trust your communication and keep it safe from Man-in-the-Middle attacks.
**Keyoxide** makes the fingerprint verification process easy for all. Add a special identity proof that not only contains your XMPP-ID but also the fingerprints of all your OMEMO keys.
If your XMPP identity proof is verified, a QR code is shown. Anyone can scan this QR code using XMPP apps like [Conversations](https://conversations.im/) (free on [F-Droid](https://f-droid.org/en/packages/eu.siacs.conversations/)) to not only add you as a contact, but also verify your OMEMO keys with the highest level of trust.
Making this identity proof yourself can be a tad difficult when using clients like Gajim, but luckily for us, [Conversations](https://conversations.im/) can directly generate the proof by going to **Manage accounts > Share > Share as XMPP URI**. The resulting URI should look something like:
```
xmpp:user@domain.org?omemo-sid-123456789=A1B2C3D4E5F6G7H8I9...
```
To take advantage of the easy and secure XMPP identity proof including OMEMO fingerprints, follow the **basic edition** guide above but replace XMPP-ID with the URI obtained through the **Conversations** app.

View file

@ -31,10 +31,6 @@ const router = require('express').Router()
const md = require('markdown-it')({typographer: true}) const md = require('markdown-it')({typographer: true})
const fs = require('fs') const fs = require('fs')
md.use(require("markdown-it-anchor"), { "level": 2, "permalink": true, "permalinkClass": 'header-anchor', "permalinkSymbol": '¶', "permalinkBefore": false })
md.use(require("markdown-it-table-of-contents"), { "includeLevel": [2, 3], "listType": "ol" })
md.use(require('markdown-it-title'))
router.get('/', (req, res) => { router.get('/', (req, res) => {
let highlights = [] let highlights = []
for (let index = 1; index < 4; index++) { for (let index = 1; index < 4; index++) {
@ -51,50 +47,10 @@ router.get('/', (req, res) => {
res.render('index', { highlights: highlights, demoData: require('../server/demo.js').data }) res.render('index', { highlights: highlights, demoData: require('../server/demo.js').data })
}) })
router.get('/about', (req, res) => {
let rawContent = fs.readFileSync(`./content/about.md`, "utf8")
const content = md.render(rawContent)
res.render(`long-form-content`, { title: `About Keyoxide`, content: content })
})
router.get('/privacy', (req, res) => { router.get('/privacy', (req, res) => {
let rawContent = fs.readFileSync(`./content/privacy-policy.md`, "utf8") let rawContent = fs.readFileSync(`./content/privacy-policy.md`, "utf8")
const content = md.render(rawContent) const content = md.render(rawContent)
res.render(`long-form-content`, { title: `Privacy policy`, content: content }) res.render(`article`, { title: `Privacy policy`, content: content })
})
router.get('/getting-started', (req, res) => {
let rawContent = fs.readFileSync(`./content/getting-started.md`, "utf8")
const content = md.render(rawContent)
res.render(`long-form-content`, { title: `Getting started`, content: content })
})
router.get('/faq', (req, res) => {
const mdAlt = require('markdown-it')({typographer: true})
mdAlt.use(require("markdown-it-anchor"), { "level": 2, "permalink": true, "permalinkClass": 'header-anchor', "permalinkSymbol": '¶', "permalinkBefore": false })
mdAlt.use(require("markdown-it-table-of-contents"), { "includeLevel": [2], "listType": "ul" })
let rawContent = fs.readFileSync(`./content/faq.md`, "utf8")
rawContent = rawContent.replace('${domain}', req.app.get('domain'))
const content = mdAlt.render(rawContent)
res.render(`long-form-content`, { title: `Frequently Asked Questions`, content: content })
})
router.get('/guides', (req, res) => {
res.render('guides', { title: `Guides - Keyoxide` })
})
router.get('/guides/:guideId', (req, res) => {
let env = {}
fs.readFile(`./content/guides/${req.params.guideId}.md`, "utf8", (err, data) => {
if (err) {
res.render(`404`)
return
}
const content = md.render(data, env)
res.render(`long-form-content`, { title: `${env.title} - Keyoxide`, content: content })
})
}) })
module.exports = router module.exports = router

View file

@ -1,71 +0,0 @@
extends templates/base.pug
block content
section.narrow
h1 Guides
.card
h2 Using Keyoxide
p
a(href='/guides/verify') Verifying a signature
br
a(href='/guides/encrypt') Encrypting a message
br
a(href='/guides/proofs') Verifying identity proofs
br
a(href='/guides/contributing') Contributing to Keyoxide
br
a(href='/guides/self-hosting-keyoxide') Self-hosting Keyoxide
h2 OpenPGP and identity proofs
p
a(href='/guides/openpgp-proofs') How OpenPGP identity proofs work
br
a(href='/guides/web-key-directory') Uploading keys using web key directory
br
a(href='/guides/signature-profiles') Using signature profiles
h2 Adding proofs
p
a(href='/guides/devto') Dev.to
br
a(href='/guides/discourse') Discourse
br
a(href='/guides/dns') Domain / DNS
br
a(href='/guides/gitea') Gitea
br
a(href='/guides/github') GitHub
br
a(href='/guides/gitlab') GitLab
br
a(href='/guides/hackernews') Hackernews
br
a(href='/guides/irc') IRC
br
a(href='/guides/lobsters') Lobste.rs
br
a(href='/guides/matrix') Matrix
br
a(href='/guides/mastodon') Mastodon
br
a(href='/guides/owncast') Owncast
br
a(href='/guides/pleroma') Pleroma
br
a(href='/guides/reddit') Reddit
br
a(href='/guides/twitter') Twitter
br
a(href='/guides/xmpp') XMPP+OMEMO
h2 Other services
p
a(href='/guides/feature-comparison-keybase') Feature comparison with Keybase
br
a(href='/guides/migrating-from-keybase') Migrating from Keybase
h2 Managing proofs in GnuPG
p
a(href='/guides/managing-proofs-listing') Listing proofs
br
a(href='/guides/managing-proofs-deleting') Deleting proofs