Keyoxide blogA modern and privacy-friendly platform to establish your decentralized online identityZola2023-10-05T18:30:18+00:00https://blog.keyoxide.org/atom.xmlKeyoxide project update 6: mobile & themeable ASP2023-10-05T18:30:18+00:002023-10-05T18:30:18+00:00
Unknown
https://blog.keyoxide.org/update-6/<h2 id="Big_mobile_app_update">Big mobile app update</h2>
<p>The mobile app now also supports verifying <a href="https://blog.keyoxide.org/ariadne-signature-profiles/">ASP profiles</a> which is a big step for this new method of creating profiles that does not require OpenPGP!</p>
<p>The latest 1.6.0 update also follows the new design recently introduced on the <a href="https://blog.keyoxide.org/2023-redesign/">Keyoxide.org website</a> as well as a host of other minor improvements and fixes. A nice touch is the new overlay that lets the user know what is happening while a profile page is loading.</p>
<p>The update should be coming to an <a rel="nofollow" href="https://keyoxide.org/apps">app store</a> near you soon!</p>
<p>For more information, do read <a rel="nofollow" href="https://berker.substack.com/p/keyoxide-mobile-160">Berker's blog post</a> on the app's update.</p>
<h2 id="Themeable_ASP_profiles_on_the_web">Themeable ASP profiles on the web</h2>
<p>On the web side of things: if you have tried the new work-in-progress <a rel="nofollow" href="https://asp.keyoxide.org">ASP web tool</a> to create your ASP profile, you will have noticed the "theme color" button which seemingly had no influence on your profile page.</p>
<p>Well, now it does: ASP profiles on the web now follow the chosen theme color! Have a look at my <a rel="nofollow" href="https://keyoxide.org/aspe:keyoxide.org:TOICV3SYXNJP7E4P5AOK5DHW44">personal ASP profile</a> with a teal theme!</p>
<h2 id="Service_provider_documentation">Service provider documentation</h2>
<p>The documentation previously made it a little difficult to find exactly which accounts Keyoxide supports and how to verify them. I hope the new <a rel="nofollow" href="https://docs.keyoxide.org/service-providers/">"Available claims/proofs" page</a> helps you as much as it does me!</p>
<h2 id="Conclusion">Conclusion</h2>
<p>This was a quick short update, we're always working on more and so, more news will follow!</p>
<p>Keyoxide is entirely open source and non-profit. If you enjoy what we do, you can help us out by <a rel="nofollow" href="https://opencollective.com/keyoxide">supporting the Keyoxide project on OpenCollective</a>.</p>
How to write a basic ASPE client2023-09-25T11:43:00+00:002023-09-25T11:43:00+00:00
Unknown
https://blog.keyoxide.org/how-to-write-aspe-client/<p>This is the third in a series of posts related to the new <a href="/ariadne-signature-profiles">Ariadne Signature Profiles</a>:</p>
<ul>
<li><a href="/how-to-create-ariadne-signature-profile">How to create an Ariadne Signature Profile</a></li>
<li><a href="/how-to-write-aspe-server">How to write a basic ASPE server</a></li>
<li><a href="/how-to-write-aspe-client">How to write a basic ASPE client</a> (you are here!)</li>
</ul>
<p>This post is intended for developers who want to create their own tools compatible with Keyoxide.</p>
<p>This post is also available in the <a rel="nofollow" href="https://docs.keyoxide.org/developers/write-aspe-client/">Keyoxide docs</a>.</p>
<h2 id="What_does_an_ASPE_client_do?">What does an ASPE client do?</h2>
<p>An Ariadne Signature Profile (ASP) is a type of identity profile that services like Keyoxide can verify but which rely on basic cryptographic standards like EdDSA and ES256 instead of cryptographic tools like OpenPGP.</p>
<p>The ASP Exchange (ASPE) protocol refers to the set of HTTP requests by which people can upload and download ASPs to and from dedicated servers.</p>
<p>An ASPE client will:</p>
<ul>
<li>let the user enter profile details and identity claims,</li>
<li>generate a cryptographic key for each profile,</li>
<li>generate JWS signatures based on that information,</li>
<li>upload those signatures to an ASPE server,</li>
<li>securely store the information and cryptographic key for later editing.</li>
</ul>
<h2 id="Writing_an_ASPE_client">Writing an ASPE client</h2>
<p>Now, let's try and write an ASPE client. This will be a simple overview of the different required steps. For more implementation details, refer to the <a rel="nofollow" href="https://ariadne.id/related/ariadne-signature-profile-0/">ASP specification</a>.</p>
<p>Here are two open source ASPE clients you can use as basis for your own:</p>
<ul>
<li><a rel="nofollow" href="https://codeberg.org/keyoxide/kx-aspe-web">kx-aspe-web</a>: a browser client,</li>
<li><a rel="nofollow" href="https://codeberg.org/keyoxide/kx-aspe-cli">kx-aspe-cli</a>: a command line client written in rust.</li>
</ul>
<h2 id="Creating_a_new_profile">Creating a new profile</h2>
<p>To create a new profile, simply create an object/struct with the following information:</p>
<ul>
<li><code>name</code> (<em>required</em>): name of the profile,</li>
<li><code>claims</code> (<em>required</em>): array of strings containing the identity claims like <code>dns:keyoxide.org?type=txt</code>,</li>
<li><code>description</code>: description of the profile,</li>
<li><code>color</code>: to be used to theme profile pages.</li>
</ul>
<p>As always with ASPs, the name of the profile may be real or anonymous. Be sure to remind your users of this fact!</p>
<p>The <a rel="nofollow" href="https://ariadne.id/related/ariadne-signature-profile-0/">spec</a> also specifies the <code>avatar_url</code> and <code>email</code> properties, but these are optional and for now, no profile verifier clients should use these yet until their behavior is better defined, so ASPE clients should omit them.</p>
<h2 id="Generating_a_cryptographic_key">Generating a cryptographic key</h2>
<p>Every ASP is identified and queried by a so-called fingerprint which is based on the cryptographic key associated with the profile. This means every ASP must have their own unique cryptographic key.</p>
<p>Indeed, the ASP method is based on the principle that cryptographic keys are cheap, single purpose and — in some way — ephemeral.</p>
<p>The spec makes opiniated decisions on which types of cryptographic keys are acceptable for the creation of an ASP. To strike a balance between reduction of code complexity of clients and freedom within the potential constraints of the client's environment, the spec allows two combinations of cryptographic keys and signature algorithm:</p>
<ul>
<li>algorithm: "EdDSA", curve: "Ed25519"</li>
<li>algorithm: "ES256", curve: "P-256"</li>
</ul>
<p>Verifying clients should always accept both of these, ASPE clients may choose to only generate profiles with a single algorithm. Indeed, at the time of writing, browsers do not widely support Ed25519 keys and are therefore restricted to P-256.</p>
<p>That being said, whenever possible, it is recommended to adopt Ed25519 over P-256. See the <a rel="nofollow" href="https://soatok.blog/2022/05/19/guidance-for-choosing-an-elliptic-curve-signature-algorithm-in-2022/">Guidance for Choosing an Elliptic Curve Signature Algorithm in 2022 [soatok.blog]</a> for more information.</p>
<p>In the next steps, the client will be generating JSON Web Signatures (<a rel="nofollow" href="https://datatracker.ietf.org/doc/html/rfc7515">JWS</a>) and according to the ASP spec, these JWS must include the cryptographic key in JSON Web Key (<a rel="nofollow" href="https://datatracker.ietf.org/doc/html/rfc7517">JWK</a>) format. Make sure that your cryptographic library of choice is capable of converting keys to the JWK format. <code>kx-aspe-web</code> uses <a rel="nofollow" href="https://www.npmjs.com/package/jose">jose (JS)</a> and <code>kx-aspe-cli</code> uses <a rel="nofollow" href="https://crates.io/crates/josekit">josekit (Rust)</a>.</p>
<h2 id="Generating_a_profile_JWS">Generating a profile JWS</h2>
<p>Now that we have profile details and a crytographic key, let's generate cryptographic signatures.</p>
<p>To upload an ASP, the client will have to generate a signature of a signature. Let's start with the "inner" signature, the <strong>profile JWS</strong>.</p>
<p>It's recommended to use tried and trusted libraries for the generation of cryptographic signatures. <code>kx-aspe-web</code> uses <a rel="nofollow" href="https://www.npmjs.com/package/jose">jose (JS)</a> and <code>kx-aspe-cli</code> uses <a rel="nofollow" href="https://crates.io/crates/josekit">josekit (Rust)</a>.</p>
<p>The object needed for the profile JWS looks as follows:</p>
<ul>
<li>the <code>typ</code> header: set to <code>JWT</code>,</li>
<li>the <code>alg</code> header: set to either <code>EdDSA</code> or <code>ES256</code>,</li>
<li>the <code>jwk</code> header: set to a valid JWK key,</li>
<li>the <code>kid</code> header: set to the key's fingerprint as obtained in <a href="https://blog.keyoxide.org/how-to-write-aspe-client/#Computing_the_fingerprint">Computing the fingerprint</a>,</li>
<li>the <code>http://ariadne.id/version</code> property: set to <code>0</code>,</li>
<li>the <code>http://ariadne.id/type</code> property: set to <code>profile</code>,</li>
<li>the <code>http://ariadne.id/name</code> property: set to profile's name,</li>
<li>the <code>http://ariadne.id/claims</code> property: set to the profile's list of identity claims.</li>
</ul>
<p>If the profile has a description and/or a color, the client may set the <code>http://ariadne.id/color</code> and the <code>http://ariadne.id/color</code> (in HEX format) respectively.</p>
<p>The JWS must be serialized using Compact Serialization (see <a rel="nofollow" href="https://datatracker.ietf.org/doc/html/rfc7515#section-3.1">section 3.1 of RFC7515</a>).</p>
<h2 id="Computing_the_fingerprint">Computing the fingerprint</h2>
<p>To obtain the fingerprint associated with the ASP profile, one must create a specific JSON object based on the JWK-encoded public key, serialize it, hash it, truncate it and encode it. All the details for this process can be found in <a rel="nofollow" href="https://ariadne.id/related/ariadne-signature-profile-0/#2-2-asp-fingerprint">section 2.2 of the spec</a>.</p>
<h2 id="Generating_a_request_JWS">Generating a request JWS</h2>
<p>The profile JWS generated above is the actual ASP that dedicated servers will host and distribute. To send the profile JWS to a dedicated server, it needs to be encapsulated for transport within a <strong>request JWS</strong>.</p>
<p>The object needed for the request JWS looks as follows:</p>
<ul>
<li>the <code>typ</code> header: set to <code>JWT</code>,</li>
<li>the <code>alg</code> header: set to either <code>EdDSA</code> or <code>ES256</code>,</li>
<li>the <code>jwk</code> header: set to a valid JWK key,</li>
<li>the <code>kid</code> header: set to the key's fingerprint,</li>
<li>the <code>http://ariadne.id/type</code> property: set to <code>request</code>,</li>
<li>the <code>http://ariadne.id/action</code> property: set to <code>create</code>,</li>
<li>the <code>http://ariadne.id/profile_jws</code> property: set to the profile JWS generated previously,</li>
<li>the <code>iat</code> property: the current UNIX epoch</li>
</ul>
<p>Evidently, the key used for the request JWS must be the same as the one used for the profile JWS.</p>
<p>Note that the <code>http://ariadne.id/action</code> property is set to <code>create</code>. This is only valid for the first upload. Subsequent uploads should use the <code>update</code> action. To remove the ASP from the server, use the <code>delete</code> action — omit the <code>http://ariadne.id/profile_jws</code> property when doing so.</p>
<p>The JWS must also be serialized using Compact Serialization (see <a rel="nofollow" href="https://datatracker.ietf.org/doc/html/rfc7515#section-3.1">section 3.1 of RFC7515</a>).</p>
<h2 id="Uploading_a_request_JWS">Uploading a request JWS</h2>
<p>Now that we have our profile JWS inside a request JWS, the client needs to upload the latter to a dedicated server. Each public ASPE server has an endpoint dedicated to receiving request JWS:</p>
<pre style="background-color:#f9f9f9;color:#111111;"><code><span>POST ENDPOINT = '/.well-known/aspe/post'
</span></code></pre>
<p>Use a POST HTTP request with the request JWS as body and set request's <code>Content-Type</code> header to:</p>
<pre style="background-color:#f9f9f9;color:#111111;"><code><span>application/asp+jwt; charset=UTF-8
</span></code></pre>
<p>If all went well, the client should receive a <strong>201 CREATED</strong> response — or <strong>200 OK</strong> for the <code>update</code> and <code>delete</code> actions.</p>
<p>The ASP is now published at the following endpoint hosted by the ASPE server:</p>
<pre style="background-color:#f9f9f9;color:#111111;"><code><span>GET ENDPOINT = '/.well-known/aspe/id/' fingerprint
</span></code></pre>
<h2 id="Securely_storing_profile_data">Securely storing profile data</h2>
<p>The client has done its duty of creating a profile and uploading it to a dedicated server. However, people may like to update or delete their profile at a later moment. It's therefore crucial to store both the profile details and the secret cryptographic key.</p>
<h3 id="Profile_details">Profile details</h3>
<p>Storing the profile details should not be an issue. <code>kx-aspe-cli</code> stores it plainly as a TOML file in the OS' user data directory — developers, don't pollute people's $HOME directory, please, thank you.</p>
<p><code>kx-aspe-web</code> takes an interesting approach: it doesn't store profile details locally but rather on the ASPE server. When editing the profile, it just fetches the profile from the server and starts from there. This has the benefit of making the profile details available on each and every device without complicated syncing protocols. Drawbacks are that people can't "prepare" an account by creating it first and uploading it later.</p>
<p>Local clients like desktop and mobile clients are strongly recommended to store a local copy of the profile.</p>
<h3 id="Secret_cryptographic_key">Secret cryptographic key</h3>
<p>This is perhaps the most delicate step of the process: people need to keep a copy of the secret key in order to keep control over their profile. But if the secret key is handled inappropriately, it becomes trivial for a bad actor to compromise that profile.</p>
<p>Some OS have dedicated key storage system like the <a rel="nofollow" href="https://developer.android.com/training/articles/keystore.html">Android Keystore</a> or the <a rel="nofollow" href="https://developer.apple.com/documentation/security/keychain_services">iOS Keychain</a> but this may not always be available or desired.</p>
<p>Based on the approach used by <a rel="nofollow" href="https://jedisct1.github.io/minisign/">Minisign</a>, both <code>kx-aspe-web</code> and <code>kx-aspe-cli</code> use scrypt to derive a key from a user-provided password and use said key to XOR the secret cryptographic key. The encrypted key resulting from the XOR operation is then either stored on the filesystem (<code>kx-aspe-cli</code>) or presented to the user to store in a password manager (<code>kx-aspe-web</code>).</p>
<p>To edit the profile at a later moment, the user must provide their password at the moment of uploading so that the secret key may be decrypted and used to sign the JWSs.</p>
<p>Note that the ASP specification does not favor a particular method for securing cryptographic keys.</p>
<h2 id="Conclusion">Conclusion</h2>
<p>Hopefully, this guide will enable more developers to create their own tools and enrich the ASP ecosystem!</p>
<p>If you enjoy the ASP profiles, you can help us by <a rel="nofollow" href="https://opencollective.com/keyoxide">supporting the Keyoxide project on OpenCollective</a>.</p>
The 2023 redesign2023-09-21T13:12:29+00:002023-09-21T13:12:29+00:00
Unknown
https://blog.keyoxide.org/2023-redesign/<h2 id="The_redesign">The redesign</h2>
<p>With version 4.1.0, <a rel="nofollow" href="https://keyoxide.org">keyoxide.org</a> has just gotten a fresh coat of paint, the most important improvement actually being something that was often mentioned to me:</p>
<blockquote>
<p>One has to scroll quite a bit to see an entire profile, there aren't many identity claims on the screen as each takes up a lot of space.</p>
</blockquote>
<p>The previous design was spacious. Perhaps a tad too much. It could fit perhaps 8 or 9 identity claims on one screen.</p>
<p>The new design fits the 20 identity claims I have on my test account, and there's still room for more.</p>
<p>See for yourself with the <a rel="nofollow" href="https://keyoxide.org/wkd/project@keyoxide.org">Keyoxide project's profile</a>! Hope you like it.</p>
<h3 id="Preparing_for_localization">Preparing for localization</h3>
<p>Another thing that the redesign diminished besides extreme roominess: the number of text elements, especially on the <a rel="nofollow" href="https://keyoxide.org">homepage</a>. It's about time that the website gets internationalization and localization, and having fewer text elements will help with this.</p>
<h3 id="The_small_things">The small things</h3>
<p>The Keyoxide website finally actually shows with version it is on in the footer. A minor change but of significant value!</p>
<p>Also, the navigation menu at the top now has a clear <code>Getting started</code> link, finally giving newcomers a clear dire</p>
<h3 id="Behind_the_scenes">Behind the scenes</h3>
<p>A big overhaul happened on the backend, which was needed to support the new <a href="/ariadne-signature-profiles/">Ariadne Signature Profiles</a>. As it turned out, after working with OpenPGP exclusively for three years, a lot of decisions had been made to the exclusive benefit of OpenPGP profiles. Think of terminology like "UserID", or the fact that profiles can only be read from cryptographic keys.</p>
<p>Now, introduce these new ASPs, which uses neither "UserId" or store the profile information as part of the cryptographic key — ASPs indeed store the profile information <em>alongside</em> the cryptographic key.</p>
<p>Subtle differences but the backend was not pleased! And now it is.</p>
<h2 id="No_more_generic_"ActivityPub"_as_service_provider!">No more generic "ActivityPub" as service provider!</h2>
<p>A small but significant improvement unrelated to the redesign: instead of simply showing "ActivityPub" for all Fediverse accounts, Keyoxide is now able to show the actual instance's "software name": Peertube, Lemmy, Mastodon, Pleroma, Akkoma, etc.</p>
<p>Unfortunately, it doesn't work for a number of instances that choose to not allow so-called cross-origin requests for their nodeinfo. A fix for this in the works!</p>
<h2 id="Conclusion">Conclusion</h2>
<p>Well, there's a quick overview of the recent changes made to the <a rel="nofollow" href="https://keyoxide.org">Keyoxide web client</a>! Hope you enjoy them as much as I do. More updates are being worked on and will get mentioned in a blog post as soon as possible!</p>
<p>The project is always looking for more contributors. If you'd like to get involved, feel free to <a rel="nofollow" href="https://docs.keyoxide.org/getting-started/community/">join the community</a> and ask questions or propose ideas.</p>
<p>If you enjoy Keyoxide, you can help out by <a rel="nofollow" href="https://opencollective.com/keyoxide">supporting the Keyoxide project on OpenCollective</a>. Thank you kindly!</p>
How to write a basic ASPE server2023-09-14T11:43:00+00:002023-09-14T11:43:00+00:00
Unknown
https://blog.keyoxide.org/how-to-write-aspe-server/<p>This is the second in a series of posts related to the new <a href="/ariadne-signature-profiles">Ariadne Signature Profiles</a>:</p>
<ul>
<li><a href="/how-to-create-ariadne-signature-profile">How to create an Ariadne Signature Profile</a></li>
<li><a href="/how-to-write-aspe-server">How to write a basic ASPE server</a> (you are here!)</li>
<li><a href="/how-to-write-aspe-client">How to write a basic ASPE client</a></li>
</ul>
<p>This post is intended for developers who want to create their own tools compatible with Keyoxide.</p>
<p>This post is also available in the <a rel="nofollow" href="https://docs.keyoxide.org/developers/write-aspe-server/">Keyoxide docs</a>.</p>
<h2 id="What_is_ASPE?">What is ASPE?</h2>
<p>We explored in the <a href="/how-to-create-ariadne-signature-profile">previous post</a> how to create an Ariadne Signature Profile. This guide made use of the <a rel="nofollow" href="https://asp.keyoxide.org">Keyoxide ASP tool</a> to create the actual profile but the profile will eventually be stored on a server that is compatible with the <em>Ariadne Signature Profile Exchange</em> (ASPE) protocol.</p>
<p>ASPE is defined in <a rel="nofollow" href="https://ariadne.id/related/ariadne-signature-profile-0/">this specification</a>. This is still a work in progress, so feel free to <a rel="nofollow" href="https://docs.keyoxide.org/community">share ideas or join the discussion</a> if you are into specs!</p>
<p>The ASP tool sends profiles to a server hosted by Keyoxide that runs <a rel="nofollow" href="https://codeberg.org/keyoxide/aspe-server-rs/">aspe-server-rs</a>, a FOSS server written in Rust. It's still new but it works and follows the spec.</p>
<p>In this guide, I will go through the different steps that an ASPE server must perform and invite you to write your own if you feel inclined to! It's not that difficult, and choice only improves ecosystems such as these.</p>
<h2 id="What_does_an_ASPE_server_do?">What does an ASPE server do?</h2>
<p>A public ASPE server will:</p>
<ul>
<li>receive and verify ASP profiles that people upload,</li>
<li>store ASP profiles,</li>
<li>send the ASP profiles upon requests.</li>
</ul>
<p>ASP profiles are encoded, stored and distributed as so-called <em>profile JWS</em>s, which in turn are sent to the ASPE server as part of so-called <em>request JWS</em>s.</p>
<p>Of course, an ASPE server could also be private, meaning people will not be able to upload their profiles to it — or only a list of pre-authorized people/profiles may do so — but the profiles that the server does store should still be publicly accessible.</p>
<h2 id="Implementing_an_ASPE_server">Implementing an ASPE server</h2>
<p>Now, let's try and implement an ASPE server! This will be a simple overview of the different required steps. For more implementation details, refer to the <a rel="nofollow" href="https://ariadne.id/related/ariadne-signature-profile-0/">ASP specification</a>.</p>
<p>I have already written a minimal ASPE server written in Rust, creatively named <a rel="nofollow" href="https://codeberg.org/keyoxide/aspe-server-rs">aspe-server-rs</a>. I will be basing this guide on that repository, so feel free to inspect the code for more context.</p>
<h2 id="Receiving_ASPs">Receiving ASPs</h2>
<p>Let's begin the guide by looking at how ASPE servers receive ASPs.</p>
<p>An ASPE server has an endpoint dedicated to receiving ASPs:</p>
<pre style="background-color:#f9f9f9;color:#111111;"><code><span>POST ENDPOINT = '/.well-known/aspe/post'
</span></code></pre>
<p>This endpoint must use HTTPS and accept POST requests. POST requests must have a so-called <em>request JWS</em> as body (see the <a href="https://blog.keyoxide.org/how-to-write-aspe-server/#Request_JWS">Request JWS</a> section).</p>
<p>Upon receiving a POST request, the server must validate the <em>request JWS</em> by checking the different values it contains as well as validating the signature. These checks are all described in the <a href="https://blog.keyoxide.org/how-to-write-aspe-server/#Request_JWS">Request JWS</a> section.</p>
<p>The server must also check the validity of the <em>profile JWS</em> contained within the <em>request JWS</em>.</p>
<p>Luckily, there are many libraries and tools to help with this validation process, including <a rel="nofollow" href="https://www.npmjs.com/package/jose">jose (JS)</a> and <a rel="nofollow" href="https://crates.io/crates/josekit">josekit (Rust)</a>. </p>
<p>If the <em>request JWS</em> is valid, the <em>profile JWS</em> it contains must be stored in a way the server implementation sees fit. See the <a href="https://blog.keyoxide.org/how-to-write-aspe-server/#Storing_ASPs">Storing ASPs</a> section. The <em>request JWS</em> must be discarded.</p>
<h2 id="Request_JWS">Request JWS</h2>
<p>A request JWS is a JSON Web Signature (<a rel="nofollow" href="https://datatracker.ietf.org/doc/html/rfc7515">RFC7515</a>) that is sent over HTTPS to transmit a so-called <em>profile JWS</em> (see the <a href="https://blog.keyoxide.org/how-to-write-aspe-server/#Profile_JWS">Profile JWS</a> section).</p>
<p>To validate a <em>request JWS</em>, make sure that:</p>
<ul>
<li>the <code>typ</code> header is set to <code>JWT</code>,</li>
<li>the <code>alg</code> header is set to either <code>EdDSA</code> or <code>ES256</code>,</li>
<li>the <code>jwk</code> header is set to a valid JWK key,</li>
<li>the <code>kid</code> header is set to the JWK Key's fingerprint as obtained in <a href="https://blog.keyoxide.org/how-to-write-aspe-server/#Computing_the_fingerprint">Computing the fingerprint</a>,</li>
<li>the <code>http://ariadne.id/type</code> property is set to <code>request</code>,</li>
<li>the <code>http://ariadne.id/action</code> property is set to <code>create</code>,</li>
<li>the <code>http://ariadne.id/profile_jws</code> property is set to a valid <a href="https://blog.keyoxide.org/how-to-write-aspe-server/#Profile_JWS">Profile JWS</a>,</li>
<li>the <code>iat</code> property is within a reasonable amount of time of the time of processing.</li>
</ul>
<p>A reasonable amount of time is subjective and requires deliberate considation from the developer. A shorter amount of time helps protect profiles against replay attacks but punishes people living in regions with poor connectivity and flaky internet. The spec recommends accepting <code>iat</code> values within an hour of the moment that the server receives the request, both before and after.</p>
<h2 id="Profile_JWS">Profile JWS</h2>
<p>A profile JWS is a JSON Web Signature that contains all the information of an ASP profile.</p>
<p>To validate a <em>profile JWS</em>, make sure that:</p>
<ul>
<li>the <code>typ</code> header is set to <code>JWT</code>,</li>
<li>the <code>alg</code>, <code>jwk</code> and <code>kid</code> headers are set to the same values as in the <em>request JWS</em>,</li>
<li>the <code>http://ariadne.id/version</code> property is set to <code>0</code> (as of this writing),</li>
<li>the <code>http://ariadne.id/type</code> property is set to <code>profile</code>,</li>
<li>the <code>http://ariadne.id/name</code> property is set,</li>
<li>the <code>http://ariadne.id/claims</code> property is set,</li>
<li>if the <code>exp</code> property is set, its value is not in the past.</li>
</ul>
<h2 id="Computing_the_fingerprint">Computing the fingerprint</h2>
<p>To obtain the fingerprint associated with the ASP profile, one must create a specific JSON object based on the JWK-encoded public key, serialize it, hash it, truncate it and encode it. All the details for this process can be found in <a rel="nofollow" href="https://ariadne.id/related/ariadne-signature-profile-0/#2-2-asp-fingerprint">section 2.2 of the spec</a>.</p>
<h2 id="Storing_ASPs">Storing ASPs</h2>
<p>The server may store ASPs in any way it sees fit, as long as it does so in a queryable manner. After all, the sole purpose of storing ASPs is to subsequently retrieve and distribute them in response to a request.</p>
<p>ASPs can only be identified and requested by their URI:</p>
<pre style="background-color:#f9f9f9;color:#111111;"><code><span>URI = 'aspe:' domain ':' fingerprint
</span></code></pre>
<p>The domain is the one used to access the ASPE server.</p>
<p>The key's fingerprint is obtained as described in <a href="https://blog.keyoxide.org/how-to-write-aspe-server/#Computing_the_fingerprint">Computing the fingerprint</a>. The fingerprint needs to be taken into consideration when implementing a storage layer for the ASPE server.</p>
<p>A simple Key-Value Database could suffice, where the fingerprint is the key and the <em>profile JWS</em> the value.</p>
<h2 id="Distributing_ASPs">Distributing ASPs</h2>
<p>The endpoint used to request ASPs from the server looks as follows:</p>
<pre style="background-color:#f9f9f9;color:#111111;"><code><span>GET ENDPOINT = '/.well-known/aspe/id/' fingerprint
</span></code></pre>
<p>Requests made to this endpoint must be GET requests.</p>
<p>If an ASP profile with the requested fingerprint was indeed stored by the ASP server and the profile is not expired (see <a href="https://blog.keyoxide.org/how-to-write-aspe-server/#Profile_JWS">Profile JWS</a>), it should be sent as the response to the request; if not, the server should return a 404 NOT FOUND.</p>
<h2 id="Allowing_servers_to_update_and_delete_ASPs">Allowing servers to update and delete ASPs</h2>
<p>Updating and deleting ASPs are basically variations on the process of uploading ASPs!</p>
<p>When the ASPE server receives a request JWS with the <code>http://ariadne.id/action</code> property set to <code>update</code>, the server should check whether it indeed already has stored an ASP with the fingerprint of the incoming ASP and whether the keys perfectly match. If all checks are positive, the server can overwrite the existing ASP with the incoming ASP.</p>
<p>Likewise, if the request JWS has the <code>http://ariadne.id/action</code> property set to <code>delete</code> and the server has found an existing ASP with a matching fingerprint, it should remove said ASP from storage.</p>
<h2 id="Conclusion">Conclusion</h2>
<p>And that's roughly all your ASPE server needs to do! Of course, a lot of details are missing from this blog post and actualy implementations should refer to the <a rel="nofollow" href="https://ariadne.id/related/ariadne-signature-profile-0">ASP spec</a> for all the information.</p>
<p>Hopefully, this guide will enable more developers to create their own tools and enrich the ASP ecosystem! Any ASP profile uploaded to such an ASPE server can be read and displayed by other tools such as <a rel="nofollow" href="https://keyoxide.org">keyoxide.org</a> and the <a rel="nofollow" href="https://mobile.keyoxide.org/">Keyoxide mobile app</a>.</p>
<p>If you enjoy the ASP profiles, you can help us by <a rel="nofollow" href="https://opencollective.com/keyoxide">supporting the Keyoxide project on OpenCollective</a>.</p>
How to create an Ariadne Signature Profile2023-08-29T10:55:43+00:002023-08-29T10:55:43+00:00
Unknown
https://blog.keyoxide.org/how-to-create-ariadne-signature-profile/<p>This is the first in a series of posts related to the new <a href="/ariadne-signature-profiles">Ariadne Signature Profiles</a>:</p>
<ul>
<li><a href="/how-to-create-ariadne-signature-profile">How to create an Ariadne Signature Profile</a> (you are here!)</li>
<li><a href="/how-to-write-aspe-server">How to write a basic ASPE server</a></li>
<li><a href="/how-to-write-aspe-client">How to write a basic ASPE client</a></li>
</ul>
<p>This post is intended for people wishing to create their own Keyoxide profile using the new ASP method!</p>
<h2 id="What_is_an_Ariadne_Signature_Profile?">What is an Ariadne Signature Profile?</h2>
<p>To prove your online identity using Keyoxide, you need an identity profile that Keyoxide can understand. Until now, such a profile had to be created with OpenPGP keys which could be a bit of a hassle. Thanks to Ariadne Signature Profiles (ASP), creating a profile is easy and straightforward.</p>
<p>More information about Keyoxide is available at <a rel="nofollow" href="https://docs.keyoxide.org/understanding-keyoxide/keyoxide/">What is Keyoxide?</a>.</p>
<h2 id="Creating_your_Ariadne_Signature_Profile">Creating your Ariadne Signature Profile</h2>
<p>The simplest way to currently create a signature profile is to visit the <a rel="nofollow" href="https://asp.keyoxide.org/">Keyoxide ASP tool</a>.</p>
<p><img src="/images/asp-1.png" alt="Create a new profile with the ASP tool" /></p>
<p>Click on the <strong>Create a new profile</strong> button. You will be asked for a password. There are no specific requirements for the passwords but be sensible and where possible, use a password manager and randomly generated passwords.</p>
<p>The ASP tool will not store the password or send it anywhere. It will use the password to encrypt your <em>secret key</em> and forget the password directly doing so. The next time you wish to edit your profile, the tool will need your <em>secret key</em> and the password to decrypt it.</p>
<p>When you confirm your password, congratulations, you have created your own ASP which Keyoxide can understand and verify! However, your profile is currently empty so let's give the profile some information.</p>
<h2 id="Adding_profile_information">Adding profile information</h2>
<p>The <strong>Edit your profile</strong> should now be visible on your screen.</p>
<p><img src="/images/asp-2.png" alt="Editing a profile with the ASP tool" /></p>
<p>Every profile needs to have a name so that people verifying your profile know what profile they are looking at. This name however can be real or anonymous! Always be careful when divulging personal information on the internet.</p>
<p>Optionally, you can also add a small description to your profile. Note that people can — and are encouraged to — have different profiles for different purposes — work, hobbies, etc. Perhaps you could explain the purpose of your profile in the description.</p>
<h2 id="Adding_identity_claims">Adding identity claims</h2>
<p>The goal of having a Keyoxide profile is to prove your online accounts so that others can verify this. An identity claim is when you claim you control a certain online account on some website or platform. Let's add one to your profile.</p>
<p><img src="/images/asp-3.png" alt="Adding an identity claim" /></p>
<p>Under <strong>Identity claims</strong>, you can select which website/platform you want to use to prove your account. At the time of writing, there are few websites/platform to choose from but know that there are many more possibilities than displayed! Simply choose <strong>Manual input</strong> and visit the <a rel="nofollow" href="https://docs.keyoxide.org/">Keyoxide docs</a> (see the <em>Available claims/proofs</em> section) to add any compatible claim to your profile.</p>
<p>Click the <strong>Add</strong> button and follow the instructions. Adding a claim is done in two steps:</p>
<ul>
<li>add some information about the <em>claim</em> like the username and/or instance domain to your profile;</li>
<li>add a <em>proof</em> to your online account.</li>
</ul>
<p>To add a <em>proof</em> to your online account, you usually need to log in to that account and add some text to your account's biography, submit a post to your timeline, or something similar. The ASP tool and the <a rel="nofollow" href="https://docs.keyoxide.org/">Keyoxide docs</a> have the exact instructions for each type of online account.</p>
<p>To know exactly what text to use as <em>proof</em>, scroll down to the <strong>Identity proofs</strong> section. The tool will present you with two proofs: the <em>direct proof</em> which is just your profile's identifier, and the <em>hashed proof</em> which is an obfuscated form of your profile's identifier. The latter is useful when you wish to hide the location of your identity profile.</p>
<p>When using <em>hashed proofs</em>, make sure to never use the same proof twice on different websites! Click the button <strong>Generate new proofs</strong> to obtain a new proof. The proofs will always be valid, no matter how many you generate.</p>
<h2 id="Securing_your_profile">Securing your profile</h2>
<p>The next step is rather important: make sure you never lose access to your profile!</p>
<p>ASPs don't work like your typical website, where you can just log in and edit your information. Each ASP is secured by a unique <em>secret key</em> and the ASP tool never stores it for security reasons. This means that is up to you to securely store your <em>secret key</em> if you ever wish to access your profile again and update the information.</p>
<p>In other words, to access your ASP in the future, you will need both the <em>secret key</em> and the <em>password</em> with which you protect the secret key. It is slightly more inconvenient than only using a password but a lot more secure!</p>
<p>Scroll down to <strong>Security</strong> to see your (encrypted) <em>Secret key</em>. Again, store this safely!</p>
<p><img src="/images/asp-4.png" alt="ASP tool security section" /></p>
<h2 id="Sharing_your_profile">Sharing your profile</h2>
<p>Next, you will find your profile's <em>fingerprint</em>. This is randomly generated and is used to identify your profile!</p>
<p>To share your profile with someone, send them your <strong>URI</strong> — which should look something like <em>aspe:keyoxide.org:ABCXYZABCXYZABCXYZ</em>. To make it even easier for the other person, you can send them straight to your Keyoxide profile page by adding your <strong>URI</strong> to the Keyoxide domain <em>keyoxide.org</em> — or, of course, the domain of a different Keyoxide instance if you use that instance.</p>
<p>That Keyoxide URL would look like <em>https://keyoxide.org/aspe:keyoxide.org:ABCXYZABCXYZABCXYZ</em>.</p>
<p>Here's a real working example: <a rel="nofollow" href="https://keyoxide.org/aspe:keyoxide.org:6WJK26YKF6WUVPIZTS2I2BIT64">https://keyoxide.org/aspe:keyoxide.org:6WJK26YKF6WUVPIZTS2I2BIT64</a></p>
<h2 id="Uploading_your_profile">Uploading your profile</h2>
<p>I mentioned above you can share your URI — or Keyoxide URL — and it should just work! Well, not yet. The ASP tool still needs to upload your profile information to the server so that others may see your profile.</p>
<p>This is simply done by clicking the <strong>Save and upload profile</strong> button and entering your password. Yes, you need to enter your password again, I told you the ASP tool wants to forget your password as soon as possible for security reasons! It is not uncommon to have to enter your password multiple times per session.</p>
<h2 id="Editing_your_profile_in_the_future">Editing your profile in the future</h2>
<p>To edit your profile in the future, visit the ASP tool again and enter your <em>Secret key</em> then click <strong>Load profile</strong>. You will be asked for your password. After that, it's business as usual as described above.</p>
<h2 id="Adding_an_avatar_to_your_profile">Adding an avatar to your profile</h2>
<p>This is still being worked on, so for now every profile gets a randomly generated avatar, see the example profile mentioned above.</p>
<h2 id="Conclusion">Conclusion</h2>
<p>There you have it, your profile!</p>
<p>If all went well, you now have a Keyoxide profile page. And of course, you have stored your secret key and password somewhere safe, preferably a password manager.</p>
<p>Because ASPs are new, there aren't any other tools yet. Hopefully soon, more developers will have created their own ASP tools. When they do, they will be added to this blog post!</p>
<p>We are still working on all these tools to make them better and easier to use. You can help us with this effort by <a rel="nofollow" href="https://opencollective.com/keyoxide">supporting the Keyoxide project on OpenCollective</a>.</p>
In testing: Ariadne Signature Profiles2023-07-14T16:58:29+00:002023-07-14T16:58:29+00:00
Unknown
https://blog.keyoxide.org/ariadne-signature-profiles/<p>I am delighted to tell you about the new Ariadne Signature Profile (ASP), the solution to creating a profile on Keyoxide without needing to use OpenPGP or the computer's command line interface.</p>
<h2 id="TL;DR">TL;DR</h2>
<p>ASPs are a new type of Keyoxide profile that are easier to create.</p>
<p>ASPs are still "in testing", things may change and profiles created during the "testing phase" may not work after the official launch — though I will do everything possible to prevent that from happening!</p>
<p>Go to <a rel="nofollow" href="https://asp.keyoxide.org">asp.keyoxide.org</a> and follow the instructions there to create your own profile with just a few clicks.</p>
<p>To verify ASP profiles, use <a rel="nofollow" href="https://dev.keyoxide.org">dev.keyoxide.org</a>. Here's an <a rel="nofollow" href="https://dev.keyoxide.org/aspe%3Akeyoxide.org%3A6WJK26YKF6WUVPIZTS2I2BIT64">example ASP profile</a>.</p>
<p>If you have feedback or noticed a bug, please do <a rel="nofollow" href="https://docs.keyoxide.org/getting-started/community/">reach out</a>!</p>
<h2 id="The_non-technical_introduction_to_ASPs">The non-technical introduction to ASPs</h2>
<p>Currently, to create an identity profile people can verify with Keyoxide tools, one must create a so-called "OpenPGP cryptographic key", store their identity claims (like "I claim to be the user @yarmo on https://fosstodon.org") inside this key and share that public key using keyservers.</p>
<p>Even the non-technical introduction gets technical quickly because it fundamentally is. There are tools to help with this process but they are not easy to use at all. Even after years of using them, they still confuse me from time to time. I wanted to create my own tools to make the process easier, but not a lot of developer libraries support the functionality that Keyoxide needs.</p>
<p>This situation has led many people to ask for easier tools and discard the Keyoxide project in the meantime.</p>
<p>For the past year, I have been working on my solution to this problem: a type of profile that does not rely on OpenPGP keys and thus allows us to create nice tools and apps to let people create their own profile.</p>
<p>These are the Ariadne Signature Profiles, or ASPs. Creating one can now be as simple as clicking a few buttons.</p>
<h2 id="Easier_to_use">Easier to use</h2>
<p>The simplest way right now to create an Ariadne Signature Profile is to go to <a rel="nofollow" href="https://asp.keyoxide.org">asp.keyoxide.org</a> and follow the instructions there!</p>
<p>In short, click the "Create a new profile" button and the tool will ask you for a password, that is all you need to create a profile!</p>
<p>Important note! After creating a profile, the tool will give you your "encrypted secret key". You need to store this somewhere on your computer or password manager as you will need this — together with your password — to update your profile. If you lose this "encrypted secret key", you will not be able to update your profile in the future.</p>
<p>I know it sounds inconvenient but it's an extra safety measure as it is bad practice to let servers touch secret keys! They are yours and yours alone and should not be shared or uploaded.</p>
<p>The ASP web tool is a work-in-progress and will get better with time, especially the translations so that more people may be able to use it in other languages.</p>
<h2 id="Local_tools">Local tools</h2>
<p>If you prefer local tools, I hear you! There is also the <a rel="nofollow" href="https://codeberg.org/keyoxide/kx-aspe-cli">kx-aspe-cli</a> command line interface, which also encrypts secret keys with passwords for safety. The CLI tool is still a work-in-progress and may be a bit rough around the edges, but it works!</p>
<p>There are no desktop apps yet as this is simply not my area of expertise. But if it is yours, feel free to experiment with ASPs, they're quite simple to work with!</p>
<p>Now that the web tool and the CLI are in public testing, we are going to work on making it possible to create profiles with the Keyoxide mobile app, which will make the process even easier! News on this will be posted on the blog as soon as possible.</p>
<h2 id="What_about_OpenPGP_profiles?">What about OpenPGP profiles?</h2>
<p>They are not going anywhere. Keyoxide was always built with the idea of giving people the choice on how they wish to create their profile. And under certain circumstances, an OpenPGP profile may be more desirable than an ASP. So it's up to you. Keyoxide will always support both types of profiles. And whatever type of profile comes next ;)</p>
<h2 id="Verifying_ASP_profiles">Verifying ASP profiles</h2>
<p>Right now, ASP profiles can only be verified using <a rel="nofollow" href="https://dev.keyoxide.org/">dev.keyoxide.org</a>. Soon, I'll enable it on the main <a rel="nofollow" href="https://keyoxide.org/">keyoxide.org</a> instance.</p>
<p>Here's an <a rel="nofollow" href="https://dev.keyoxide.org/aspe%3Akeyoxide.org%3A6WJK26YKF6WUVPIZTS2I2BIT64">example ASP profile</a>.</p>
<h2 id="Documentation">Documentation</h2>
<p>There is no user documentation yet on regarding ASPs, I am working on this and will publish it for the official ASP launch.</p>
<p>For developers, there is the <a rel="nofollow" href="https://ariadne.id/related/ariadne-signature-profile-0/">ASP spec</a>.</p>
<p>Everyone is of course welcome to join the <a rel="nofollow" href="https://docs.keyoxide.org/getting-started/community/">community</a> for any questions or feedback they might have! </p>
<h2 id="Conclusion">Conclusion</h2>
<p>Once we officially make ASPs stable, we'll have truly lowered the barrier of entry to creating Keyoxide profiles and made decentralized online identity verification accessible to a broader audience.</p>
<p>If you like Keyoxide and want to see it go further, please consider making a donation on our <a rel="nofollow" href="https://opencollective.com/keyoxide">OpenCollective</a>, thank you.</p>
Live on OpenCollective!2023-03-28T17:17:22+00:002023-03-28T17:17:22+00:00
Unknown
https://blog.keyoxide.org/opencollective/<h2 id="Working_as_a_Collective">Working as a Collective</h2>
<p>The Keyoxide project is now live on <a rel="nofollow" href="https://opencollective.com/keyoxide">OpenCollective</a>! This will make it easier to receive donations, pay the monthly costs of running the servers and even opens the possibility to reward important code contributions!</p>
<p>As per the model of OpenCollective, all transactions are public and auditable. Many thanks to <a rel="nofollow" href="https://opencollective.com/europe">Open Collective Europe</a> for hosting the project!</p>
<p>To celebrate this moment, Keyoxide has added the ability to verify OpenCollective accounts! See it in action here on the <a rel="nofollow" href="https://keyoxide.org/44a875dcbef777e79d7cca3ecc5764283d461ad1">project's Keyoxide page</a>.</p>
<p>If you like Keyoxide and want to see it go further, please consider making a donation on our <a rel="nofollow" href="https://opencollective.com/keyoxide">OpenCollective</a>, thank you.</p>
Keyoxide Community Call: March 20232023-03-10T10:55:34+00:002023-03-10T10:55:34+00:00
Unknown
https://blog.keyoxide.org/community-call-march-2023/<h2 id="Community_call_on_March_18th,_2023">Community call on March 18th, 2023</h2>
<p>The Keyoxide project will be holding a Community Call on March 18th, 2023 at:</p>
<ul>
<li>15:00 <a rel="nofollow" href="https://time.is/UTC">UTC</a></li>
<li>09:00 <a rel="nofollow" href="https://time.is/CT">US Central Time</a></li>
</ul>
<p>Everybody is welcome to join the <a rel="nofollow" href="https://meet.jit.si/moderated/7fe17e2a9457fa99fee1624708ba9f8662fc06e214de9dba9ed4f53a3c29f918">jitsi meeting</a> and ask questions.</p>
<p>The agenda and minutes will be available in the <a rel="nofollow" href="https://codeberg.org/keyoxide/community-calls/src/branch/main/calls/2023-03-18.md">keyoxide/community-calls repository</a>.</p>
How to create an online identity, part 1: using OpenPGP2023-03-08T19:58:24+00:002023-03-08T19:58:24+00:00
Unknown
https://blog.keyoxide.org/create-openpgp-profile/<h2 id="Introduction">Introduction</h2>
<p>You have seen someone's Keyoxide profile like <a rel="nofollow" href="https://keyoxide.org/id">this one</a> and now you want to create your own page just like that, including verifiable identities!</p>
<p>Eventually, there will be at least three methods to create such a profile, including using only an app on a phone! For now, there is only one method: using OpenPGP in the command line. Not very user-friendly, agreed, but if you have some patience and the will to experiment (or you are already tech-savvy), we can get there!</p>
<p>If you'd rather not play around with the command line, please stay tuned and keep an eye on the blog.</p>
<p>This guide is a more expanded version of the <a rel="nofollow" href="https://docs.keyoxide.org/getting-started/creating-profile/">creating a profile</a> on the Keyoxide documentation but contains the same steps and procedures.</p>
<h2 id="Get_your_system_ready">Get your system ready</h2>
<p>Regardless of whether you are using the Linux, Windows or macOS operating system, your computer will have a "terminal" or a "command line". You can start it as you start any other application, the only difference is there are no buttons, no nice graphics, just a big textbox waiting for your input. It may seem scary but it really isn't!</p>
<p>Next, we need one tool: GnuPG, also known as gpg. This is an application like any other, except it doesn't have a graphical interface, and thus can only be used with the terminal or command line.</p>
<p>On Linux, <code>gpg</code> is usually already installed, if not use your distribution's package manager.</p>
<p>On Windows, install Gpg4win from the <a rel="nofollow" href="https://www.gpg4win.org/">offical website</a>. It comes with Kleopatra but sadly, that graphical tool doesn't do what we need for Keyoxide. Luckily, it also install <code>gpg</code> for the terminal/command line.</p>
<p>On macOS, install GPGTools from the <a rel="nofollow" href="https://gpgtools.org/">official website</a>.</p>
<p>Once the tools are installed, open a new terminal or command line.</p>
<h2 id="Generate_a_cryptographic_key">Generate a cryptographic key</h2>
<p><em>If you already have an OpenPGP key, feel free to skip this chapter.</em></p>
<p>We use so-called cryptographic keys as the medium to create and distribute our online passports, as explained in the <a href="/nontechnical-introduction/">nontechnical introduction to Keyoxide</a>. To be more precise, we will generate a cryptographic keypair that follows the OpenPGP standard. Because it is standardized, it will be easy for others to interact with your cryptographic key.</p>
<p>A keypair consists of a private key which you will keep secret and stored only on your computer and a public key that you will publish openly. The private key is used to issue yourself your online passport, the public key is used to distribute your online passport.</p>
<p>In the terminal that you have opened, run the following command:</p>
<pre data-lang="bash" style="background-color:#f9f9f9;color:#111111;" class="language-bash "><code class="language-bash" data-lang="bash"><span style="color:#c82728;">gpg</span><span style="color:#f07219;"> --full-gen-key --expert
</span></code></pre>
<p>Not to worry, the <code>--expert</code> flag will not make it more complicated, it just allows us to select a specific type of key, namely the <code>Curve 25519</code>.</p>
<p>Next, type <code>10</code> then press enter to select <code>(10) ECC (sign only)</code>.</p>
<p>Next, type <code>1</code> then press enter to select <code>(1) Curve 25519</code>.</p>
<p>Great, now gpg knows what kind of key we want! Now, we need to set an expiration date. It is advisable to set an expiration date so that if you ever lose your private key, your online passport will invalidate itself after a certain period of time.</p>
<p>Of course, as long as you don't lose your private key, you will be able to keep moving the expiration farther in the future so it won't invalidate itself while you're still using it.</p>
<p>To set the expiration date two years later, type <code>2y</code> and press enter. Confirm with <code>y</code> and press enter. Set a reminder in your calendar for one year later to update the expiration date. The procedure is explained below.</p>
<p>Next, you enter your name and press enter. Note that this may be your real name or your online pseudonym. Remember that for your online passport, you don't actually need to be known by your real name! This is cyber space, be who you want to be!</p>
<p>You also need to enter a valid email address. This one needs to be valid and actually exist, as you will receive an email to confirm your key.</p>
<p><em>Remember those future methods I told you will soon exist to create a profile? They won't need you to provide an email address! So if you'd rather not make your email address publicly known, please wait until the future methods are here.</em></p>
<p>You will also be asked for a comment. This one is optional so feel free to skip it if you don't feel like including an arbitrary message.</p>
<p>To confirm all your "personal" data is correct, enter <code>O</code> (as in, <strong>O</strong>kay) and press enter.</p>
<p>You will now be asked for a password. Obviously, it is <strong>strongly</strong> recommended to use a password, and a unique one at that, stored in a password manager. You will need the password every time you make a change to your online passport.</p>
<p>After this, you should be all done! You now have the medium to hold and distribute your online passport.</p>
<p>Your cryptographic key has a unique identifier, also called the <strong>fingerprint</strong>. To find it, in the terminal, run:</p>
<pre data-lang="bash" style="background-color:#f9f9f9;color:#111111;" class="language-bash "><code class="language-bash" data-lang="bash"><span style="color:#c82728;">gpg</span><span style="color:#f07219;"> -K
</span></code></pre>
<p>You should find one (or more) keys, find the one you just created which has the name and email address you entered a few minutes ago. Next to the line starting with <code>sec</code>, you should see a sequence of 40 characters that looks like <code>5DC026DDD293736A3B305F42B6558943003E6A70</code> but with different characters. That is your key's fingerprint, copy this becuase you will need it a couple of times in the following procedures.</p>
<h2 id="Add_identities_to_your_cryptographic_key">Add identities to your cryptographic key</h2>
<p>You have issued yourself your own online passport, congratulations! However, your passport is currently empty. You need to fill it with your online identities, your online accounts that you want to prove are yours.</p>
<p>To add an identity to your passport, you must perform two steps:</p>
<ol>
<li>link your online passport to your online account (i.e. the <em>claim</em>);</li>
<li>link your online account to your online passport (i.e. the <em>proof</em>).</li>
</ol>
<p>This creates a <em>bidirectional link</em> and is the concept that Keyoxide uses to prevent impersonation. Everyone can <em>claim</em> your online account, but only you can <em>prove</em> which claim is the true one!</p>
<h3 id="Proving_a_Fediverse_account">Proving a Fediverse account</h3>
<p>It may seem counterintuitive, but it's easier to first <em>prove</em> an identity, then <em>claim</em> it.</p>
<p>So, let's say we want to prove & claim an account on the Fediverse, for example on a Mastodon server. Log into your Mastodon account, go to <strong>Edit profile</strong> and add the following URI:</p>
<pre style="background-color:#f9f9f9;color:#111111;"><code><span>openpgp4fpr:FINGERPRINT
</span></code></pre>
<p>to either:</p>
<ol>
<li>one of your "metadata" links,</li>
<li>your "about me" section.</li>
</ol>
<p>Of course, you replaced <code>FINGERPRINT</code> with your own fingerprint, right? :) That first part <code>openpgp4fpr:</code> tells Keyoxide where to go looking for fingerprints.</p>
<p>That's it, you have linked your Mastodon account to your cryptographic key. In other words, you have "proved" one of your online identities. Now, let's claim it!</p>
<h3 id="Claiming_a_Fediverse_account">Claiming a Fediverse account</h3>
<p>In the terminal (the same one, or a new one!), run:</p>
<pre data-lang="bash" style="background-color:#f9f9f9;color:#111111;" class="language-bash "><code class="language-bash" data-lang="bash"><span style="color:#c82728;">gpg</span><span style="color:#f07219;"> --edit-key</span><span style="color:#4271ae;"> FINGERPRINT
</span></code></pre>
<p>Again, replace <code>FINGERPRINT</code> with your own fingerprint.</p>
<p>Now, you write <code>notation</code> and press enter. gpg wants you to enter a notation, which is what we will use to put identity claims inside our online passports. One notation for each identity claim.</p>
<p>Write the following:</p>
<pre style="background-color:#f9f9f9;color:#111111;"><code><span>proof@ariadne.id=https://FEDIVERSE_SERVER/@USERNAME
</span></code></pre>
<p>Never change <code>proof@ariadne.id=</code>, this is a requirement by the people who invented and improved OpenPGP. You will have to replace <code>FEDIVERSE_SERVER</code> and <code>USERNAME</code>.</p>
<p>For example, the official Keyoxide project profile has the following notation:</p>
<pre style="background-color:#f9f9f9;color:#111111;"><code><span>proof@ariadne.id=https://fosstodon.org/@keyoxide
</span></code></pre>
<p>Press enter, and you should be asked for your password. Write <code>save</code>, press enter and you are done!</p>
<p>Your cryptographic key now links to your Mastodon acccount. You have "claimed" your online identity!</p>
<h3 id="Uploading_your_online_passport">Uploading your online passport</h3>
<p>Congratulations, you now have a fully functional online passport, including an identity claim and an identity proof waiting for someone to verify your identity claim!</p>
<p>But no one can access it yet. Not even Keyoxide. Your online passport only lives on your computer. So let's upload it to a public keyserver!</p>
<p>Public keyservers are services people can use to upload their public keys, and this is how we will publish our online passport. Remember that we are only uploading the public half of our cryptographic keypair, this half is <em>meant</em> to be shared publicly, every one can read it but it can't be used to alter your online passport.</p>
<p>Keyoxide strongly recommends to use <a rel="nofollow" href="https://keys.openpgp.org">keys.openpgp.org</a> for uploading your public keys. It's fully open source and developed by some very smart people. There are other keyservers out there but they have some flaws that don't play nicely with Keyoxide.</p>
<p>If this is your first time uploading your key to keys.openpgp.org, you need to perform the following steps:</p>
<ol>
<li>In your terminal, run: <code>gpg --armor --output public.asc --export FINGERPRINT</code>;</li>
<li>Using your OS' file manager, locate the <code>public.asc</code> file you have created in step 1;</li>
<li>Go to <a rel="nofollow" href="https://keys.openpgp.org/upload">keys.openpgp.org/upload</a> and upload the <code>public.asc</code> file;</li>
<li>Check the email address you entered when creating your key, it will receive a verification email, click on the link it contains.</li>
</ol>
<p>Done! You can now visit <a rel="nofollow" href="https://keyoxide.org">keyoxide.org</a> and search for your fingerprint or email address, both will work!</p>
<p>It may take up to an hour before your identity claim reliably shows the green tick.</p>
<p>There you go, you have created a Keyoxide profile! You can share your Keyoxide link with anyone and let them verify your claims for themselves.</p>
<h3 id="Uploading_your_online_passport_after_the_first_time">Uploading your online passport after the first time</h3>
<p>Once you've done the whole email verification process, no need to ever go through these steps again (unless you add an email address). In the terminal, run:</p>
<pre data-lang="bash" style="background-color:#f9f9f9;color:#111111;" class="language-bash "><code class="language-bash" data-lang="bash"><span style="color:#c82728;">gpg</span><span style="color:#f07219;"> --keyserver</span><span style="color:#4271ae;"> hkps://keys.openpgp.org</span><span style="color:#f07219;"> --send-keys</span><span style="color:#4271ae;"> FINGERPRINT
</span></code></pre>
<p>Done!</p>
<h3 id="Setting_your_avatar">Setting your avatar</h3>
<p>If you want to add an avatar to your profile, create an account on <a rel="nofollow" href="https://www.libravatar.org/">libravatar.org</a> and associate a picture with the email address you used for your cryptographic key.</p>
<h3 id="Closing_remarks">Closing remarks</h3>
<p>Using Keyoxide really gets interesting once you claim & prove more than one online account, as that is how you establish a unified online presence. One Keyoxide profile to link all your online identities!</p>
<p>Have a Twitter account? <a rel="nofollow" href="https://docs.keyoxide.org/service-providers/twitter/">Claim and prove it</a>. Have a personal website? <a rel="nofollow" href="https://docs.keyoxide.org/service-providers/dns/">Claim and prove it</a>. Have a Reddit account? <a rel="nofollow" href="https://docs.keyoxide.org/service-providers/reddit/">Claim and prove it</a>.</p>
<p>Find many more services to verify in the <a rel="nofollow" href="https://docs.keyoxide.org/">Keyoxide documentation</a>.</p>
<p>Do you have another online account you wish to verify but Keyoxide doesn't support it yet? <a rel="nofollow" href="https://docs.keyoxide.org/community">Let us know</a>!</p>
A nontechnical introduction to Keyoxide and online identity verification2023-03-07T13:05:22+00:002023-03-07T13:05:22+00:00
Unknown
https://blog.keyoxide.org/nontechnical-introduction/<h2 id="Introduction">Introduction</h2>
<p>This nontechnical introduction was originally given as a lightning talk at FOSDEM 2023 on February 5th, the recording of which can be viewed below. This post is the written counterpart of that talk.</p>
<video controls>
<source src="https://video.fosdem.org/2023/H.2215%20(Ferrer)/keyoxide.webm">
</video>
<h2 id="The_IRL_passport">The IRL passport</h2>
<p>Before we tackle online identity verification, let's have a look at in-real-life identity verification.</p>
<img src="/images/cartoon-irl-passport.png" alt="Cartoon about in-real-life passports" style="max-width: 360px">
<p>A passport is used as an identifying document but is a nonfunctional document in and of itself. Granted, it contains a picture of the holder and the paper itself usually has holographic protection, but assuming an actor with sufficient resources and motivation, these can be convicingly imitated. </p>
<p>A passport gains function when it is verified and checked with the government that issued it to ensure the document is authentic. But even then, this guarantees the document is authentic and still valid, but does not ensure the person presenting it is the same as whom it was issued to.</p>
<p>Passports are difficult-but-not-impossible to counterfeit and aren't actually tied the person to whom it was issued. Could we do better if we were trying to design an identity system for our digital selves?</p>
<h2 id="Do_we_need_online_identity?">Do we need online identity?</h2>
<p>Whether we like it or not, the digital realm is slowly but surely invading our lives in the physical world. And more and more crucial human interactions are happening through digital pathways. While some of those might arguably have been better left untouched by the internet, others could have never existed without it: think of remote working and online conferences attended by people worldwide.</p>
<p>Not all online interactions need verifiability, but it is hard to imagine some without: think of organizers of dissent. They may need to use different platforms of communication and thus it is imperative to know who you are talking with on each of them, to avoid communicating the right information to the wrong people. And in the unfortunate case of compromised communication, they wouldn't want their real life identity associated with their online identity.</p>
<p>Maintaining verifiable online identities present unique challenges but by combining the appropriate tools and techniques, it is possible to offer tailored solutions.</p>
<h2 id="A_simple_example_scenario">A simple example scenario</h2>
<img src="/images/cartoon-kx-rationale.png" alt="Cartoon about why we need online identity" style="max-width: 360px">
<p>Let's imagine two characters, Alice and Bob. Note that these may or may not be their real names. They have been speaking to each other for years using Matrix.</p>
<p>On a day, Alice gets a message from a certain "Bob91" on a fictional network named XYZ. Alice wonders if this is an account made by her friend Bob. But how could she confirm this?</p>
<p>Assuming she currently is unable to directly ask Bob on Matrix, she needs a way to verify Bob's different online identities. She needs a tool that isn't necessarily tied to a real-life identity, but which proves beyond doubt that the same person who created the "Bob" account also created the "Bob91" account on XYZ.</p>
<p>Of course, the opposite must also be true: the tool must be resistant to impersonation attacks, making sure that someone isn't able to successfully verify accounts they did not create or do not manage.</p>
<h2 id="Requirements_and_constraints">Requirements and constraints</h2>
<p>So, assuming we were to create the digital equivalent of the passport. What would it look like? What would it do? How would different parties interact with it?</p>
<p>The most basic requirement - and also conceptually the most challenging - is <strong>uniqueness</strong>. Something about our hypothetical digital passport should be unique to prevent impersonation. If a passport is not unique, anyone could generate that passport and assume anyone else's identity.</p>
<p>This is challenging since a passport also needs to be <strong>verifiable</strong> and thus <strong>shareable</strong>. In the digital world, there is no sparsity. Any sequence of zeros and ones can be copied and replicated an infinite amount of times. Share a photo online with 10 friends. They could all right-click on that photo and store a copy it on their devices. What started as one picture is now eleven pictures, perfectly identical and indistinguishable. Nothing about the original made it unique, and thus all are now the original.</p>
<p>What we need is some secret information that we could keep to ourselves, and a way to generate some derivative information that is somehow linked to our secret information but does not reveal it. What we need is a one-way function. Luckily, there are solutions for this thanks to cryptography, more on this in a later blog post.</p>
<p>If implemented correctly, this uniqueness will make it <strong>secure</strong>, ensuring that only one person can write the identity information and yet everyone can read it. And no one else can modify that identity data.</p>
<p>Another important requirement is <strong>self-sovereignty</strong>. If we can trust the uniqueness of the passport, we don't need to have to trust or involve an external authority. Every digital citizen should be able to issue their own piece of identification.</p>
<p>An interesting requirement flows directly from self-sovereignty: <strong>anonymity</strong>. If one is able to issue their own passport, what prevents them from issuing multiple passports?</p>
<p>The answer is <em>nothing</em>. And that is not a flaw. We can be and indeed are different beings in the digital realm and this should be celebrated and protected.</p>
<p>Now, we know what requirements our identity solution has to meet. Let's have a bird's eye view of how all this can be accomplished with Keyoxide.</p>
<h2 id="Introducing_Keyoxide">Introducing Keyoxide</h2>
<p>Let's go back to Alice and Bob.</p>
<p>Bob needs a way to let others verify his online identities. Sure, he could take the easy way and just create a single google account and rely entirely on that. After all, through that account, he has access to a lot of google services, and plenty more where he can just log into with his google account.</p>
<p>Fortunately for him, he is aware people lose their google accounts daily due to misfiring automated systems and knows that once this happens, there is usually no way to get it back. All your logins, all your mails, all your contacts, all your files and photos, gone because of bad AI.</p>
<p>Bob wants to be in charge of his own online identity and not rely on a big internet corporation.</p>
<p>Using so-called cryptographic tools, Bob creates a cryptographic keypair. For the purpose of this nontechnical introduction, let us visualize the cryptographic keypair as a glass vault.</p>
<p>As its name suggests, a keypair consists of two files. A secret key and a public key. Only Bob has access to the secret key, and thus can store things inside the glass vault. Bob will give the public key to anyone who wants it, allowing them to see inside the glass vault, but no one other than Bob can change what is stored inside the vault.</p>
<p>So, what does Bob choose to put inside the vault?</p>
<p>He writes a document that contains his name (real or not!) and a list of all his accounts: his Matrix account, his Fediverse accounts, his Twitter account if he still has it, etc. And this document, he stores in his glass vault. He then uploads the public key to a keyserver so that is available for everyone to see.</p>
<p>Is Bob done? Not really. Of course, everyone now knows which accounts Bob claims to use. But that is all they are: claims.</p>
<p>Let's meet Mallory. Mallory is trying to scam Alice by pretending to be Bob. So she does the same thing Bob just did: generate a cryptographic keypair, write a document with a list of all of Bob's accounts (and one of his own!) and upload it to a keyserver.</p>
<p>How could Alice ever know which keypair is the right one? She can't unless the claims are somehow verified.</p>
<p>It is important to know that each keypair (glass vault) has a unique identifier, known as a fingerprint. Without going into details, this system is practically safe and ensures every key really has a unique identifier: for SHA2 with 256 bits, there are 115792089237316195423570985008687907853269984665640564039457584007913129639936 (around 116 quattuorvigintillion, give or take) possible fingerprints, and it can go higher than that!</p>
<p>So yeah, the chance of two people accidentally getting the same fingerprint is fairly small.</p>
<p>Bob takes his keypair's fingerprint and puts in his accounts: he adds it to his Fediverse account's Biography, he sends it as a tweet.</p>
<p>Now, Alice has a way to distinguish Bob's real key from Mallory's fake key. Both keys contain a reference to the Fediverse account, but the Fediverse account only has a reference back to a single key. So that has to be Bob's key.</p>
<p>Unless of course Mallory has broken into Bob's Fediverse account, but then Bob has bigger issues.</p>
<p>So that is how Bob creates his online identity and allows others to verify it, while at the same time warding off imposters.</p>
<p>Notice how this post hasn't mentioned Keyoxide yet. That's because Keyoxide is not strictly necessary for this whole process. This method of online identity verification relies entirely on existing tools, infrastructure and good practices.</p>
<p>Of course, verifying one or two accounts shouldn't be too time consuming, but once profiles contain 10 or 20 or more accounts, it just becomes a hassle. And that's where Keyoxide steps in, helping by automating the whole identity verification process, taking only a few seconds to verify large numbers of accounts.</p>
<p>Here, take a look at this example Keyoxide profile: <a rel="nofollow" href="https://keyoxide.org/44a875dcbef777e79d7cca3ecc5764283d461ad1">keyoxide.org/44a875dcbef777e79d7cca3ecc5764283d461ad1</a>. It contains a claim of a domain name: <em>keyoxide.org</em>.</p>
<p>To verify this manually, you could just use any DNS text resolver such as <a rel="nofollow" href="https://mxtoolbox.com/SuperTool.aspx?action=txt%3akeyoxide.org&run=toolpage">this one</a>. And sure enough, there is the fingerprint you are looking for: <em>44a875dcbef777e79d7cca3ecc5764283d461ad1</em>.</p>
<p>Keyoxide is simply trying to make your life easier by doing this for you, and repeating the process for all the other claims.</p>
<h2 id="How_can_you_get_started?">How can you get started?</h2>
<p>Currently, it's not too simple to create your own Keyoxide profile, you would have to know your way around your computer's command line. This is because Keyoxide is helping people verify other's identities, but does not help yet with setting up the identities in the first place.</p>
<p>This is being worked on and as soon as the apps are ready, we'll share the news right here on the blog!</p>
Launching the Keyoxide Chat Bot2023-02-22T14:13:49+00:002023-02-22T14:13:49+00:00
Unknown
https://blog.keyoxide.org/chat-bot/<h2 id="A_new_conversational_interface">A new conversational interface</h2>
<p>Today, I am publishing the source code for the new Keyoxide chat bot and launching a Telegram chat bot that runs it.</p>
<p>The chat bot is a different way to verify people's online identities. Instead of visiting <a rel="nofollow" href="https://keyoxide.org/test@doip.rocks">https://keyoxide.org/test@doip.rocks</a> in a browser, one is now able to open the Telegram app on any platform, start a conversation with the <a rel="nofollow" href="https://t.me/keyoxidebot">Keyoxide bot</a> and send it the following message:</p>
<pre style="background-color:#f9f9f9;color:#111111;"><code><span>/profile test@doip.rocks
</span></code></pre>
<p>to get the results below:</p>
<img src="/images/keyoxide_telegram_bot_sample.png" style="max-width: 320px">
<h2 id="Open_source">Open source</h2>
<p>The chat bot is written in rust and open source, as everything related to the Keyoxide project is. Find the <a rel="nofollow" href="https://codeberg.org/keyoxide/keyoxide-chat-bot">source code on Codeberg</a>.</p>
<h2 id="On_Telegram_first">On Telegram first</h2>
<p>Start a conversation with the bot by scanning the QR code below:</p>
<img src="/images/keyoxide_telegram_bot_qr.png" style="max-width: 120px">
<p>As I already had experience with programming Telegram bots, I decided to program the bot for that platform first. Of course, I would love to add a Matrix bot and an IRC bot. And while we're at it, a XMPP bot too?</p>
<p>Currently, I have plenty of other tasks I must prioritize. As the code is open source, you are invited to contribute if you'd like to see support for those platforms as soon as possible!</p>
XMPP Proofs: now better than ever!2022-12-12T16:09:19+00:002022-12-12T16:09:19+00:00
Unknown
https://blog.keyoxide.org/xmpp-proofs/<h2 id="TLDR">TLDR</h2>
<p>XMPP identity verification through Keyoxide is fixed and now works better than before!</p>
<p>Use the <strong>XMPP Ariadne Proof Utility</strong> (<a rel="nofollow" href="https://xmpp-util.keyoxide.org/">xmpp-util.keyoxide.org</a>) to upload and manage your identity proofs in your XMPP account.</p>
<h2 id="Introduction">Introduction</h2>
<p>Soon after writing my <a href="/xmpp-claims-vcard/">Keyoxide, XMPP claims and vCard</a> blog post, I was contacted by Matthew Wild, Prosody developer and maintainer of <a rel="nofollow" href="https://snikket.org/">Snikket</a> and he told me (paraphrasing for brevity but he was a lot more cordial!):</p>
<blockquote>
<p>You've got the facts right but the whole system wrong.</p>
</blockquote>
<p>What did I get wrong exactly?</p>
<h2 id="Misusing_the_vCard_system">Misusing the vCard system</h2>
<p>Since Keyoxide needs to fetch some public data location of your XMPP account to find your identity proof, I chose to store identity proofs in the vCard data. At the time, this was publicly available through <a rel="nofollow" href="https://xmpp.org/extensions/xep-0054.html">XEP-0054: vcard-temp</a> and thus a good fit for Keyoxide.</p>
<p>But it is important to remember that hosting publicly available data is NOT the purpose of the vCard system: it is made for hosting personal data and sharing it with your contacts.</p>
<p><a rel="nofollow" href="https://xmpp.org/extensions/xep-0292.html">XEP-0292: vCard4 over XMPP</a>, to which the XMPP ecosystem is transitioning to, fixes this with a configurable access model that defaults to contacts-only access. A great development for the XMPP users! But not so great for Keyoxide.</p>
<p>In my <a href="/xmpp-claims-vcard/">Keyoxide, XMPP claims and vCard</a> blog post, I explained how I was trying to fight the vCard system and how I figured I lost.</p>
<p>Then came the incredibly helpful Matthew Wild who taught me how to use the system to my advantage.</p>
<h2 id="Seeing_PubSub_in_a_different_light">Seeing PubSub in a different light</h2>
<p>Talking to Matthew, I learned among many other things that <a rel="nofollow" href="https://xmpp.org/extensions/xep-0163.html">XEP-0163: Personal Eventing Protocol</a> is an extremely versatile beast, is used by XMPP clients to store preferences and can even be used to store public data as described in <a rel="nofollow" href="https://xmpp.org/extensions/xep-0222.html">XEP-0222</a>.</p>
<p>In other words, why try and misuse the vCard data if we can just store the identity proof data in a different space where it can be made public?</p>
<p>It all seems so obvious now.</p>
<h2 id="The_new_XMPP_identity_Proof">The new XMPP identity Proof</h2>
<p>So, from now on, that is exactly how XMPP identity verification is going to work: identity proofs are stored directly using the PubSub protocol in the XMPP account, in a dedicated public PubSub node that anyone can fetch to verify your identity.</p>
<p>To upload and manage identity proofs on your XMPP account, I am releasing the <strong>XMPP Ariadne Proof Utility</strong>, hosted at <a rel="nofollow" href="https://xmpp-util.keyoxide.org/">xmpp-util.keyoxide.org</a>. It is of course <a rel="nofollow" href="https://codeberg.org/keyoxide/xapu">open source</a>, and built on top of the <a rel="nofollow" href="https://github.com/snikket-im/xmpp-account-exporter">XMPP account exporter</a> utility built by Matthew Wild.</p>
<p>The utility runs entirely in the browser and no personal data or credentials are stored or shared. It's a static HTML page so feel free to host it yourself or simply download it and open it locally.</p>
<p>Of course, Keyoxide will still check vCard data for backward compatibility, but I strongly recommend switching over to the new vCard-less identity proofs.</p>
<h2 id="A_lesson_for_the_future">A lesson for the future</h2>
<p>There is something much bigger to be learned here: talk more and earlier with knowledgeable people and experts, and don't hesitate to do so.</p>
<p>Sometimes, Keyoxide is hampered because services don't have public APIs or lack the necessary infrastructure to support hosting proofs. For example, it is often needed to publish identity proofs inside an account's Biography section to make it publicly available, something for which the Biography section was not designed.</p>
<p>And indeed, up until now, XMPP didn't have dedicated infrastructure for hosting identity proofs.</p>
<p>But instead of going ahead and try misusing existing infrastructure, knowledgeable people and experts can help better understand the existing infrastructure and use it to one's advantage. And this was without a doubt the case here.</p>
<h2 id="Signing_off">Signing off</h2>
<p>A huge thanks to Matthew Wild for helping me understand XMPP and PubSub to a much higher degree and assisting me in the creation of this utility.</p>
<p>It fills me with joy to know that Keyoxide can now verify XMPP accounts and that we won't need to worry about anything anymore: no vCard transitioning, no server-specific configurations. <a rel="nofollow" href="https://compliance.conversations.im/test/xep0163/">Nearly all XMPP servers support XEP-0163</a> and thus support proving accounts with identity proofs uploaded and managed with tools such as <a rel="nofollow" href="https://xmpp-util.keyoxide.org/">xmpp-util.keyoxide.org</a>.</p>
<p>Happy XMPP account proving to all!</p>
<p>Yarmo</p>
Keyoxide, XMPP claims and vCard2022-12-04T11:31:27+00:002022-12-12T16:09:19+00:00
Unknown
https://blog.keyoxide.org/xmpp-claims-vcard/<h2 id="TLDR">TLDR</h2>
<p>XMPP identity verification through Keyoxide is no longer possible for the foreseeable future due to a period of transitionining between vCard standards in the XMPP ecosystem.</p>
<p><strong>UPDATE ON 2022-12-12</strong>: XMPP account verification has been fixed and improved, here's the <a href="/xmpp-proofs/">blog post</a>.</p>
<h2 id="Introduction">Introduction</h2>
<p>Back when Keyoxide started in 2020 and I added verification of XMPP accounts, it didn't work too well. It turned I didn't fully understand XMPP and vCard. A few fixes later, it worked much better.</p>
<p>For about a month now, I have been receiving more and more complaints about XMPP identity verification no longer working for many. I couldn't look into it at first due to a busy schedule, but I have been doing some digging the last few days and I think I understand what is going wrong. Sadly, due to the nature of the issue, it won't be easy to fix and this will probably mean for the foreseeable future, people won't be able to add XMPP claims to their Keyoxide profiles.</p>
<p>I have been talking to XMPP developers and their words and advice have led me to the conclusions in this post. If I have misunderstood anything or failed to see the entire picture, do let me know and I will correct the post.</p>
<h2 id="How_Keyoxide_and_XMPP_work_together">How Keyoxide and XMPP work together</h2>
<p>As with all Keyoxide cl2022-12-03-xmpp-claims-vcardims and proofs, identity is established through bidirectional linking: your cryptographic key points to your XMPP account, your XMPP account points back to your key.
2022-12-03-xmpp-claims-vcard
I am a latecomer to the XMPP party so I do not pretend to know the entire lore, but from what I can gather, XMPP <em>official</em> support for vCard started in 2002 with <a rel="nofollow" href="https://xmpp.org/extensions/xep-0054.html">XEP-0054 vcard-temp</a>. It states:</p>
<blockquote>
<p>This specification documents the vCard-XML format currently in use within the Jabber community. A future specification will recommend a standards-track protocol to supersede this informational document.</p>
</blockquote>
<p>It appears XMPP servers were already implementing vCard in a non-standardized way, this XEP was meant to standardize the practice temporarely until a new more intentional XEP was published and solved all vCard issues. XEP-0054 was last updated in 2008.</p>
<p>This brings us to <a rel="nofollow" href="https://xmpp.org/extensions/xep-0292.html">XEP-0292 vCard4 over XMPP</a>, first published in 2010. It states:</p>
<blockquote>
<p>This document specifies an XMPP extension for use of the vCard4 XML format in XMPP systems, with the intent of obsoleting the vcard-temp format.</p>
</blockquote>
<p>The XEP has been worked for a couple of years but for reasons that I do not know, it has not been adopted twelve years later and in fact is now in a "deferred" state — I have been assured by a XMPP developer this doesn't actually mean anything for the future of the XEP. XEP-0292 is likely the candidate to supersede vcard-temp, the timeline for this is simply unclear.</p>
<p>So, what should XMPP servers and clients support? Again, I do not have a definitive answer but it appears it is up to the individual projects to decide which "standard" to support.</p>
<h2 id="The_old_complaints">The old complaints</h2>
<p>Receiving complaints from people not getting their XMPP claims and proofs to work is nothing new to the project. As I have mentioned before, especially in Keyoxide's first year, XMPP support was pretty rough.</p>
<p>For example, it was only after a while that I found out some clients/servers store vCard notes as a "note" node, and others as a "desc" node. With Keyoxide now configured to look into both nodes, this solved the issue for many. But still, some were experiencing identity verification issues.</p>
<p>Later still, I found out about Prosody's <a rel="nofollow" href="https://prosody.im/doc/modules/mod_vcard_legacy">restrict vCard access</a> setting. If the server2022-12-03-xmpp-claims-vcardl was fine again.</p>
<h2 id="The_new_complaints">The new complaints</h2>
<p>Since about a month ago, I have been receiving more XMPP-related complaints. The people followed the guides and Keyoxide would still refuse to verify their accounts.</p>
<p>Once I looked into the issue, I found something surprising: their vCard data that I obtained through vcard-temp was not the data they claimed to have put there. vcard-temp would give me their old vCard data. I thought this could be a rogue server issue, but then found out it happened to people on different servers. And it happenend to people on the same server that I use. And yet my identity verification was working fine!</p>
<p>A few days ago, I finally sat down and started debugging. My XMPP identity proof was still working!</p>
<p>I use <a rel="nofollow" href="https://dino.im">Dino</a> as my daily client but it doesn't allow one to change their vCard data, so I installed <a rel="nofollow" href="https://gajim.org">Gajim</a>. Can I just say, what a wonderful client that has become!</p>
<p>Anyway, oddity #1: I clicked on the <strong>Profile</strong> button where one goes to update vCard data and found it… Empty. Strange. I <em>did</em> have vCard data. I checked my public page on <a rel="nofollow" href="https://mov.im">mov.im</a>, yup, I really did still have vCard data. Why isn't Gajim showing that data?</p>
<p>I didn't think much of it and entered some of my personal details again. Including a new note that would act as identity proof.</p>
<p>It updated successfully and the new note was also displayed on mov.im.</p>
<p>Oddity #2: I asked Keyoxide to fetch my vCard data through vcard-temp and it received… The OLD VCARD DATA!</p>
<p>Oh, so the server must have switched to vCard4 then?</p>
<p>Oddity #3: I asked Keyoxide to fetch my vCard data through vcard4-over-xmpp and I received… An error message that vCard4 was not supported on this server.</p>
<p>I was baffled. Where did my vCard data go to? And how come mov.im and Gajim know the new data, and I still get old data?</p>
<p>I sent a desperate message to the fediverse, was recommended to talk to a XMPP developer room and that's when everything became clear.</p>
<h2 id="The_lengthy_vCard_transition">The lengthy vCard transition</h2>
<p>As I mentioned earlier, it appears XMPP projects decide for themselves whether to continue supporting vcard-temp or switch to vCard4. And the tools I recommend for Keyoxide appear to have made the switch.</p>
<p><em>But wait, I thought the server said vCard4 was not supported?</em></p>
<p>Apparently, I have been asking the server for the wrong thing.</p>
<p>Allow me to introduce you to <a rel="nofollow" href="https://xmpp.org/extensions/xep-0060.html">XEP-0060 Publish-Subscribe</a>. As I have had little time to mentally wrestle with this fella, I'm not 100% certain I see the entire picture here, but it appears that's how XMPP projects expose their vCard data nowadays.</p>
<p>The way I read <em>XEP-0292 vCard4 over XMPP</em>, it proposes two methods of obtaining vCard4 data:</p>
<ul>
<li><a rel="nofollow" href="https://xmpp.org/extensions/xep-0292.html#self-iq">IQ calls</a></li>
<li><a rel="nofollow" href="https://xmpp.org/extensions/xep-0292.html#self-pubsub">event notifications</a> through the aforementioned Publish-Subscribe</li>
</ul>
<p>I tried the IQ calls for vCard requests on several servers but none of them supported it. I tried the event notifications and lo and behold, the missing updated vCard data surfaced!</p>
<p>Conclusion? Two years ago, Gajim and mov.im must have supported vcard-temp and that's how I entered my vCard data back then. This is also how Keyoxide retrieved the vCard data used to verify accounts.</p>
<p>Somewhere between two years ago and today, both Gajim and mov.im must have transitioned to support vCard4 — through PubSub, not IQ calls! Indeed, this was the case for <a rel="nofollow" href="https://gajim.org/post/2021-02-08-gajim-1.3.0-released/">Gajim 1.3.0</a>, released early 2021.</p>
<p>So now, Keyoxide should simply switch to vCard4 with PubSub and all is well. Right?</p>
<h2 id="A_happy_ending?">A happy ending?</h2>
<p>Well, this is where things get awkward.</p>
<p>See, the old vcard-temp system had a bit of a flaw: data was always public — unless you used Prosody's <em>restrict vCard access</em>. Granted, this flaw is what allowed Keyoxide's identity verification to work in the first place, but still, publicly exposing your vCard data should at the least be opt-in.</p>
<p>The new vCard4 system fixes that — or so I have been told that one day it will. Remember that we can only access the vCard4 data through the Publish-Subscribe interface? Well, acquiring data through Publish-Subscribe requires a "Subscription". A Subscription is easily requested but needs to be approved by the account we subscribe to.</p>
<p>This means that in order to verify a XMPP account, I need my Keyoxide XMPP verifier account to subscribe to that XMPP account, wait for them to accept it and only then it will work. And that is not acceptable behavior.</p>
<p>First of all, Keyoxide does not know beforehand which XMPP account holds an identity proof and which don't, meaning a bad actor could simply make my Keyoxide XMPP verifier account spam subscriptions to many XMPP accounts that want nothing to do with account verification.</p>
<p>And second, Keyoxide is decentralized. Each Keyoxide instance needs a separate XMPP verifier account. And each XMPP verifier account will also need to subscribe to each and every XMPP account.</p>
<p>This is obviously a lose-lose situation. Keyoxide can only use publicly available vCard data lest it becomes a spam account.</p>
<p>And currently, there is no other way to obtain publicly available vCard data. The XMPP ecosystem has entered the awkward phase of the vCard transition where the major clients no longer support vcard-temp but servers only partially support vCard4 over XMPP. This is not enviable position for the ecosystem to be in and I wish the XMPP developers all the strength to push through this phase and come out with a solid vCard system.</p>
<p>As for Keyoxide, verification of XMPP accounts used to work, and will again at some time in the future, but in the current state of affairs, it doesn't. Or at least not easily.</p>
<h2 id="What_now?">What now?</h2>
<p>For those with already working XMPP account verification, great! Don't change your key and your proof will continue to work.</p>
<p>For those who wish to verify a new XMPP account, I currently cannot help you, sorry. The tools no longer exist.</p>
<p>While I do not envy the XMPP developers for this unavoidable awkward phase, I will provide one piece of constructive criticism. By transitioning the major XMPP clients from vcard-temp to vCard4 from one version to the next without a period of supporting both at the same time, it has been made impossible for people to actually migrate their vCard data. Yes, I can just enter my new data as vCard4 but I can no longer delete my vcard-temp data! As I have been led to believe that privacy concerns play a role in this transition, I find it odd that it is deemed acceptable to let my old vcard-temp exist in a read-only state for all to see and not give me the tools to delete it.</p>
<p>How is that <em>constructive</em> criticism? Well, I believe there's an opportunity here: I think the XMPP community should build a dedicated tool to delete vcard-temp data. I for one would use such a tool once the vCard transition is considered complete.</p>
<p>And I will not lie: if such a tool could also edit vcard-temp data, that would of great benefit to the Keyoxide project and the people wishing to verify their accounts.</p>
<p>Note: there already could be such a tool out there that I simply haven't found yet. If so, please do let me know and I will update this post accordingly.</p>
<p>In my imagination, such a tool could take the form of a Gajim plugin or at the very least, export the XML commands to be entered in the Gajim XML Console.</p>
<h2 id="Signing_off">Signing off</h2>
<p>So there you have it. To the best of my knowledge, people can no longer verify XMPP accounts until there's either a vcard-temp editor tool, or vCard4 data can be accessed publicly without the subscription requirement.</p>
<p>Again, I wish the XMPP community nothing but the best in this transition period.</p>
<p>When the situation improves, I'll be sure to post an update!</p>
<p><strong>UPDATE ON 2022-12-12</strong>: XMPP account verification has been fixed and improved, here's the <a href="/xmpp-proofs/">blog post</a>.</p>
<p>Yarmo</p>
This Month in Keyoxide: November 20222022-11-30T17:17:39+00:002022-11-30T17:17:39+00:00
Unknown
https://blog.keyoxide.org/keyoxide-november-2022/<h2 id="🏠_Keyoxide_project">🏠 Keyoxide project</h2>
<h3 id="keyoxide-blue">keyoxide-blue</h3>
<p>The last few days, I've been developing <a rel="nofollow" href="https://keyoxide.blue">keyoxide.blue</a>, a new experimental Keyoxide web client, both as a distraction and as a way to test out a few potential new features. Yes, I will be using it as a playground, so:</p>
<ol>
<li>Expect things to work</li>
<li>Be prepared for things to be broken</li>
<li>Do join the fun and suggest new interesting features</li>
</ol>
<p>Of course, it's <a rel="nofollow" href="https://codeberg.org/keyoxide/keyoxide-blue">open source</a> and all the identity verification logic runs in the browser (except for the calls to a proxy server) so you will need JS enabled for this one.</p>
<p>Putting some time into keyoxide-blue has had a few benefits. I could re-evaluate just how much effort was needed at the bare minimum to make a basic frontend for the <a rel="nofollow" href="https://codeberg.org/keyoxide/doipjs">doip.js</a> library. Any additional work the frontend needed to perform that wasn't strictly about nicely presenting a profile is something perhaps the library should have done instead.</p>
<p>While this side project has shown me how to improve the doip.js library, it has also confirmed that little work is actually needed to integrate the library in any website and get identity verification going.</p>
<p><em>So, Keyoxide Blue. What hidden message is lurking behind that name? What does it refer to? Surely it's a parody of Tw…</em></p>
<p>I was thinking about the word <em>oxide</em>. I figured I could write it out as <code>#0c51de</code> (ocside) to turn that word into a hexadecimal color code. That color turns out to be blue. The specific blue used on the page.</p>
<h2 id="🚧_DOIP_libraries">🚧 DOIP libraries</h2>
<h3 id="Fediverse_post_proofs">Fediverse post proofs</h3>
<p>Not much happened this month in DOIP development. It is now possible to verify Fediverse accounts by posting the proof in a message and using the link to the post as the identity claim. Handy for people on Pixelfed who get limited space for their bio section!</p>
<h2 id="📄_Ariadne_Specification">📄 Ariadne Specification</h2>
<h3 id="The_New_Ariadne_Specification">The New Ariadne Specification</h3>
<p>This month, I have focused a significant share of my efforts to finishing and publishing a new Ariadne Identity Specification (AIS), a rewrite that I have been preparing for months. It's now public on <a rel="nofollow" href="https://ariadne.id">ariadne.id</a>.</p>
<p>The previous attempt at getting the Ariadne spec going was too convoluted and unwieldy. This time, it's a simple static website built around Markdown files. It's source code is on <a rel="nofollow" href="https://codeberg.org/ariadne/ariadne-identity-specification">Codeberg</a>. The contribution process still needs to be ironed out but at least, we can get going.</p>
<p>The new AIS implementation is based around three sections:</p>
<ul>
<li>the Core Specification: this describes the entire identity verification process</li>
<li>the Related Specifications: these describe protocols that enhance the identity verification process</li>
<li>the ARCs: these describe the different service providers and how to verify accounts on them</li>
</ul>
<p>I think this arrangement makes a lot of sense. To write a new AIS-compatible project, one should only need to look at the Core Specification for the fundamental logic and the ARCs for how to apply it to different service providers.</p>
<p>For example, the Core Specification describes how identity claims and profiles are stored inside OpenPGP keys as notations or as cryptographic signatures. The ARCs then describe what to do with these identity claims. Once stable, the Core Specification should rarely be changed while a new ARC should be published every time a new online service is to be supported.</p>
<p>As for Related Specifications, these may describe protocols that aren't <em>fundamental identity verification logic</em> but still are of benefit to the process, like the Web Signature Directory specification.</p>
<h3 id="Web_Signature_Directory">Web Signature Directory</h3>
<p>I love the <a rel="nofollow" href="https://datatracker.ietf.org/doc/draft-koch-openpgp-webkey-service/">Web Key Directory</a> specification. It's a simple way to publish OpenPGP keys on any server — abolishing the need for centralized keyservers — and discover them using email addresses as identifiers. It can be used on personal servers or as the basis for a <a rel="nofollow" href="https://keys.openpgp.org/about/usage#wkd-as-a-service">WKD-as-a-service</a> platform.</p>
<p>This is the perfect infrastructure on which to build Keyoxide. Profiles are stored inside OpenPGP keys, OpenPGP keys are published and discovered using WKD. The user entirely controls the key and where it is stored. To delete your Keyoxide profile, just delete it from the WKD server.</p>
<p>But OpenPGP is finicky to work with. A great tool for the PC power user, a nightmare for anyone else. Building user-friendly tooling is also tricky as very few libraries support the exotic OpenPGP features Keyoxide needs.</p>
<p>So, in addition to Keyoxide-profiles-as-OpenPGP-keys, I want to add support for Keyoxide-profiles-as-cryptographic-signatures and have received a <a rel="nofollow" href="https://blog.keyoxide.org/nlnet-2/">NLnet grant</a> to do just that.</p>
<p>While experimenting with signature profiles started nearly <a rel="nofollow" href="https://blog.keyoxide.org/keyoxide-project-update-2/">two years ago</a>, the idea has now matured and the time has come to definitively implement it and more importantly, build the infrastructure needed to host cryptographic signatures just as easily as cryptographic keys.</p>
<p>And what better inspiration for such an infrastructure than the Web Key Directory protocol?</p>
<p>I introduce <a rel="nofollow" href="https://ariadne.id/related/web-signature-directory-0/">version 0 of the Web Signature Directory specification</a>. It's largely based on WKD and adapted for the purposes of cryptographic signatures. It's tool-agnostic so it can work with any cryptographic tool such as OpenPGP, minisign, SSH, etc. It has an HTTP-based update protocol that is even designed to work with JS-less HTML forms. It's easily implemented on single-tenant servers and should be simple to turn into a multi-tenant WSD-as-a-service platform.</p>
<p>Since it's version 0, I do not recommend building implementations yet unless it's a toy implementation. This version is meant to receive critical review to fix issues and risks before we start building the real implementations.</p>
<p>If looking into specifications and protocols is your thing, I would much appreciate constructive criticism to improve WSD. As always, discussions are welcome on any of the <a rel="nofollow" href="https://docs.keyoxide.org/community/">community channels</a>.</p>
<h2 id="Signing_off">Signing off</h2>
<p>This has been yet another big month for the project, even though you won't see the effects right away. Recent space billionaire drama has driven huge traffic to the Fediverse and a portion of those eyeballs have seen mentioning of the Keyoxide project.</p>
<p>With the increased exposure of people to Keyoxide has come the fair criticism on the complicated process of creating a profile. With the new protocols and specifications coming into place, we can now start building the tools and interfaces to make Keyoxide a much greater joy to get started with.</p>
<p>And I for one can't wait to see that happen.</p>
<p>Until next time,<br />
Yarmo</p>
<hr />
<p>If you like the Keyoxide project and would like to see it go further, I hope you
will consider making a donation as well, through
<a rel="nofollow" href="https://liberapay.com/Keyoxide/">Liberapay</a>
(recurring) or
<a rel="nofollow" href="https://ko-fi.com/keyoxide">Ko-fi</a>
(one-time). This helps me stay working full-time on Keyoxide and pay for the
servers. Thanks for considering!</p>
This Month in Keyoxide: October 20222022-10-30T16:27:50+00:002022-10-30T16:27:50+00:00
Unknown
https://blog.keyoxide.org/keyoxide-october-2022/<h2 id="🏠_Keyoxide_project">🏠 Keyoxide project</h2>
<h3 id="Keyoxide_Mobile_version_1.2.0">Keyoxide Mobile version 1.2.0</h3>
<p>The Keyoxide mobile app's latest 1.2.0 update comes with a list of improvements
and bug fixes:</p>
<ul>
<li>Setting an user profile for quick access</li>
<li>Improved layout (buttons, settings)</li>
<li>Improved sharing of links</li>
<li>Improved theming</li>
</ul>
<p>The maintainer Berker also did a lot of code rewriting and restructuring to
prepare the app for some major planned improvements, that will make it much
easier to interact with Keyoxide profiles and we both honestly can't wait for
these updates to see the light of day. More announcements to follow!</p>
<p>And thanks again for all your time and dedication, Berker!</p>
<p>Relevant links:</p>
<ul>
<li><a rel="nofollow" href="https://berker.substack.com/p/keyoxide-mobile-120">Berker's announcement</a></li>
<li><a rel="nofollow" href="https://f-droid.org/en/packages/org.keyoxide.keyoxide/">Keyoxide Mobile on F-Droid</a></li>
<li><a rel="nofollow" href="https://codeberg.org/keyoxide/keyoxide-flutter">keyoxide-flutter source code</a></li>
</ul>
<h3 id="Widgets_in_the_documentation">Widgets in the documentation</h3>
<p>Keyoxide is complex. To use and to explain. It just has a complex nature. And
the documentation should help with that.</p>
<p>Slowly but surely, the documentation is becoming more interactive. A few weeks
ago, I introduced a
<a rel="nofollow" href="https://docs.keyoxide.org/understanding-keyoxide/identity-proof-formats/#Hashed_URI">simple widget</a>
to help people with hashing their identity proofs.</p>
<p>Today, I am releasing the
<a rel="nofollow" href="https://docs.keyoxide.org/guide/">Keyoxide interactive guide</a>
. The user experience is a work in progress and I am open to suggestions but it
should already give an impression on how interactive documentation can help
tackle tasks that are quite difficult to explain using static linear
documentation.</p>
<p>You can tell the guide what your Keyoxide profile is and what account you wish
to verify, and it will generate a list of steps that you need to perform to
actually do so. For example, if I wish to claim the <code>keyoxide.org</code> domain name
with my Keyoxide profile using a hashed proof, here are the required steps in a
<a rel="nofollow" href="https://docs.keyoxide.org/guide/?profile_id=9f0048ac0b23301e1f77e994909f6bd6f80f485d&claim_uri=dns%3Akeyoxide.org%3Ftype%3DTXT&proof_type=argon2">guide tailored to me</a>
: just press the "Get guide" button!</p>
<p>The guide will also provide feedback whether both the claim and the proof were
correctly made. If so, you have successfully claimed a part of your online
identity!</p>
<p>This is a first step upon which more and more helpful interactive widgets can be
built.</p>
<p>Relevant links:</p>
<ul>
<li><a rel="nofollow" href="https://docs.keyoxide.org/understanding-keyoxide/identity-proof-formats/#Hashed_URI">Keyoxide documentation on hashed proofs</a></li>
<li><a rel="nofollow" href="https://docs.keyoxide.org/guide/">Keyoxide interactive guide</a></li>
</ul>
<h2 id="🚧_DOIP_libraries">🚧 DOIP libraries</h2>
<p>The DOIP libraries are the brains behind the Keyoxide website and apps. They are
<a rel="nofollow" href="https://codeberg.org/keyoxide/doipjs">open source</a> and available for everyone.</p>
<h3 id="Universal_ActivityPub_claim_verification">Universal ActivityPub claim verification</h3>
<p>Finally, we can verify all ActivityPub claims!</p>
<p>Previously, it had been a bit hit and miss. Pleroma and Mastodon would work
fine, Pixelfed would be recognized as Pleroma (due to their similar URL syntax),
others wouldn't work… And if an instance required signed HTTP requests, it
wouldn't work at all.</p>
<p>Now, this has all been solved: Keyoxide no longer makes a distinction between
the various fediverse server apps. If it speaks ActivityPub, Keyoxide can verify
it. All current and future servers. And all the HTTP requests Keyoxide makes are
now signed, so any instance with "secure mode" turned on can now have their
identities verified!</p>
<p>This update comes with a downside: all ActivityPub-related claims are now marked
as <code>activitypub</code>, the interface can no longer distinguish Pleroma, Pixelfed,
Peertube, Mastodon… This is being worked on!</p>
<p>Relevant links:</p>
<ul>
<li><a rel="nofollow" href="https://docs.joinmastodon.org/spec/security/">Mastodon documentation on HTTP signatures</a></li>
</ul>
<h2 id="📄_Ariadne_Specification">📄 Ariadne Specification</h2>
<h3 id="Status_of_the_Specification">Status of the Specification</h3>
<p>First, a word on the status of the Ariadne Specification. It is currently
outdated as I have realized the approach I was using wasn't working — slow and
tedious to update. Next month, I will reboot the Ariadne specification with a
simpler approach, I will provide an update and request feedback as soon as I
have something to show.</p>
<h3 id="Ariadne_Implementation_Test_Suite">Ariadne Implementation Test Suite</h3>
<p>This update, I am particularly excited about. Did you know the awesome folks
over at
<a rel="nofollow" href="https://sequoia-pgp.org/">Sequoia PGP</a>
built an
<a rel="nofollow" href="https://tests.sequoia-pgp.org/">OpenPGP interoperability test suite</a>
that they use to test and compare various OpenPGP implementations?</p>
<p>Well, I really like their concept. This month, I built my own version of this
but for software implementations of the Ariadne Specification. The space is
still young so there's only one implementation right now, the
<a rel="nofollow" href="https://codeberg.org/keyoxide/doipjs">doip.js</a>
library. But hey, it's being tested right now and soon as others pop up, they
will become part of this automated testing as well!</p>
<p>I introduce the <a rel="nofollow" href="https://tests.ariadne.id/">Ariadne Implementation Test Suite</a>.</p>
<p>The way it works is simple: the test uses a list of identity claims known to
verify and tests the library against each one. The test suite asks to verify
correct and incorrect fingerprints: an implementation can't just reply
"verified" to every claim verification, it actually needs to do the work!</p>
<p>For this test suite to work, we need a standardized interface for all
implementations. Inspired by how the OpenPGP interoperability test suite
achieves this, I wrote a Stateless Command Line Interface for my library, the
<a rel="nofollow" href="https://codeberg.org/keyoxide/scli-doipjs">scli-doipjs</a>
. This interface can be called from a terminal to perform the most fundamental
tasks that the library must be able to do. Currently, this is only verifying
identity claims but this will be expanded to reading cryptographic keys and
verifying entire profiles.</p>
<p>The syntax for the SCLI is still being considered, feel free to
<a rel="nofollow" href="https://docs.keyoxide.org/community/">join the community</a>
and participate in the discussion.</p>
<p>Running the test suite yourself is pretty simple, you just need a bunch of
accounts with correct proofs (and access tokens for certain services like
Twitter, Telegram…):</p>
<ul>
<li>get the <a rel="nofollow" href="https://codeberg.org/keyoxide/ariadne-implementation-test-suite">source code</a></li>
<li>make a <a rel="nofollow" href="https://codeberg.org/keyoxide/ariadne-implementation-test-suite/src/branch/main/config.template.toml">configuration file</a></li>
<li>run <code>cargo run -- --export-html</code></li>
</ul>
<p>Written in Rust 🦀</p>
<p>Relevant links:</p>
<ul>
<li><a rel="nofollow" href="https://tests.sequoia-pgp.org/">OpenPGP interoperability test suite</a></li>
<li><a rel="nofollow" href="https://tests.ariadne.id/">Ariadne Implementation Test Suite</a></li>
<li><a rel="nofollow" href="https://codeberg.org/keyoxide/scli-doipjs">scli-doipjs</a></li>
</ul>
<h3 id="Automated_alerts_for_claims_that_suddenly_stop_working">Automated alerts for claims that suddenly stop working</h3>
<p>The Ariadne Implementation Test Suite described above gave me another idea.</p>
<p>It has happened more that once during the last two years that I would wake up to
a series of complaints from people whose identity claims suddenly would no
longer verify. And sometimes, this was not due to a mistake on my part but
rather something happening with a service provider that changed something in
their API response, modified an API endpoint…</p>
<p>I have given the Ariadne Implementation Test Suite a second purpose: it will run
at a regular interval and send me notifications (using webhooks) when claims
that would previously verify no longer do so.</p>
<p>Getting this to work on your machine/server is pretty simple. Assuming you have
an endpoint for webhooks:</p>
<ul>
<li>get the <a rel="nofollow" href="https://codeberg.org/keyoxide/ariadne-implementation-test-suite">source code</a></li>
<li>make a <a rel="nofollow" href="https://codeberg.org/keyoxide/ariadne-implementation-test-suite/src/branch/main/config.template.toml">configuration file</a></li>
<li>run <code>cargo run -- --trigger-webhooks</code> at a regular interval (i.e. using cron jobs)</li>
</ul>
<p>I have it set up on my server and this will help me detect errors when they
occur and hopefully even deploy fixes before the first bug reports arrive!</p>
<h2 id="Signing_off">Signing off</h2>
<p>This has been a busy month, and in a way, I'm glad for this! So far, since the
project has started two years ago, I have been able to work on it full-time
thanks to a minimalist lifestyle and donations from the community and
<a rel="nofollow" href="https://nlnet.nl/">NLnet</a>
.</p>
<p>And there is still lots to do!</p>
<p>If you like the Keyoxide project and would like to see it go further, I hope you
will consider making a donation as well, through
<a rel="nofollow" href="https://liberapay.com/Keyoxide/">Liberapay</a>
(recurring) or
<a rel="nofollow" href="https://ko-fi.com/keyoxide">Ko-fi</a>
(one-time). This helps me stay working full-time on Keyoxide and pay for the
servers. Thanks for considering!</p>
<p>Well, time to get back at it. The coming month will be dedicated to the Ariadne
Specification as well as releasing a few other improvements to Keyoxide I have
been working on. Hope to tell you more about this as soon as I can!</p>
<p>Yarmo</p>
Hashing identity proofs2022-09-22T10:03:37+00:002022-09-22T10:03:37+00:00
Unknown
https://blog.keyoxide.org/hashing-identity-proofs/<h2 id="Introduction_to_claims_and_proofs">Introduction to claims and proofs</h2>
<p>As explained in the <a rel="nofollow" href="https://docs.keyoxide.org/understanding-keyoxide/identity-claims-proofs/">Keyoxide documentation on identity claims and
proofs</a>,
an identity <strong>claim</strong> is a link that connects your Keyoxide profile to an online
account on some website or app, and an identity <strong>proof</strong> is the link that connects
said account to said Keyoxide profile.</p>
<img src="https://blog.keyoxide.org/processed_images/explaining-identity-claims-proofs.78a4cc1c3f9b60ff.png" />
<p>When the claim links to the proof and the proof links to the claim, we call this
<strong>bidirectional linking</strong> and this is what Keyoxide uses to verify online
identities.</p>
<h2 id="Concealing_the_proof">Concealing the proof</h2>
<p>It makes sense for your Keyoxide profile to link to all these accounts — after
all, that is the reason to use Keyoxide in the first place: link all your
accounts together.</p>
<p>But sometimes, it might make sense to not have your account link back to your
Keyoxide profile, especially if you are an activist or are otherwise prone to
online harassment. If ill-intentioned people find one of your accounts with a
proof, it's a small effort to then find your Keyoxide profile using that proof
and find your other accounts.</p>
<p>Let us find a solution for this situation.</p>
<p>Keyoxide still needs a functional proof to verify your online identity but it
shouldn't have to reveal your Keyoxide profile.</p>
<h2 id="Introduction_to_cryptographic_hash_functions">Introduction to cryptographic hash functions</h2>
<p>I know, it sounds complicated. But at a basic level, it really isn't.</p>
<p><a rel="nofollow" href="https://en.wikipedia.org/wiki/Cryptographic_hash_function">Wikipedia</a> says:</p>
<blockquote>
<p>A cryptographic hash function is a mathematical algorithm that maps data of an
arbitrary size to a bit array of a fixed size.</p>
</blockquote>
<p>Hmmm, ok. Let's look at some examples using the <strong>md5</strong> algorithm.</p>
<pre style="background-color:#f9f9f9;color:#111111;"><code><span>Input: 123
</span><span>Hash: 202cb962ac59075b964b07152d234b70
</span></code></pre>
<p>There are many online md5 hash generators online which will all give the same results.</p>
<p>So I gave a md5 hash algorithm <em>123</em> as input and it returned a piece of text of 32
characters. Another example:</p>
<pre style="background-color:#f9f9f9;color:#111111;"><code><span>Input: What a day, what a lovely day!
</span><span>Hash: 4135aae5be97419e1a2b447d60dba630
</span></code></pre>
<p>The hash is different but still 32 characters long.</p>
<pre style="background-color:#f9f9f9;color:#111111;"><code><span>Input: It was a bright cold day in April, and the clocks were striking thirteen.
</span><span>Hash: a0a0268ce44df858b5b62b873eb28c32
</span></code></pre>
<p>The input is much longer now and still the hash is only 32 characters long!</p>
<p>So, a hash is like a fingerprint of the input, no matter how long it is. It's
also unique to each input — well, not exactly but it's extremely difficult to
find two inputs that have the same hash.</p>
<p>More importantly, hash functions are <strong>one-way functions</strong>: if you know the
input, it's very easy to calculate the hash. If you know the hash, it's very
complicated to calculate the input! </p>
<p class="warning">md5 is unsafe to use for sensitive data! I used it here to
illustrate how hash functions work, but no more using md5 after this point!</p>
<h2 id="Applying_hash_functions_to_identity_proofs">Applying hash functions to identity proofs</h2>
<p>So, how does this help us?</p>
<p>Let's look at an example:
<a rel="nofollow" href="https://keyoxide.org/3637202523e7c1309ab79e99ef2dc5827b445f4b">keyoxide.org/3637202523e7c1309ab79e99ef2dc5827b445f4b</a>.</p>
<p>It contains a single identity claim: the <a rel="nofollow" href="https://doip.rocks">doip.rocks</a>
website.</p>
<p>To verify this identity claim, Keyoxide fetches some data associated to this
website — in this case, the DNS records. Keyoxide will then go looking inside
this data and will consider the identity claim verified if it finds the
following piece of text:</p>
<pre style="background-color:#f9f9f9;color:#111111;"><code><span>openpgp4fpr:3637202523e7c1309ab79e99ef2dc5827b445f4b
</span></code></pre>
<p>If someone accidentally finds this proof, they can then find your Keyoxide
profile. This may not be an issue for some, but it could be for others! So,
let's conceal the proof using a hash function.</p>
<p>Go to the <a rel="nofollow" href="https://keyoxide.org/util/bcrypt">Keyoxide bcrypt tool</a> and give it
the following input:</p>
<pre style="background-color:#f9f9f9;color:#111111;"><code><span>openpgp4fpr:3637202523e7c1309ab79e99ef2dc5827b445f4b
</span></code></pre>
<p>The bcrypt algorithm is quite different from md5 — every time you generate a
hash, you get a different one! — but much more secure.</p>
<p>Here is one of the valid hashes that website will generate:</p>
<pre style="background-color:#f9f9f9;color:#111111;"><code><span>$2a$11$VOT3WZZArNB4zKNQBDKGLeSOkB6d2wnHt4vbP1GmF6SyCQjucQIgK
</span></code></pre>
<p>Now, I can use this as proof and Keyoxide will consider the identity claim
verified. And if someone finds this proof by accident, there is no way of
figuring out what the associated Keyoxide profile is!</p>
<h2 id="Beware,_not_a_silver_bullet!">Beware, not a silver bullet!</h2>
<p>It is important to note that hashing proofs is NOT infallible. Yes, it will
conceal the fingerprint but if someone already knows your Keyoxide profile, they
may expose the concealed fingerprint through different channels.</p>
<h2 id="Keyoxide_and_hash_functions">Keyoxide and hash functions</h2>
<p>Keyoxide currently supports the <strong>bcrypt</strong> and <strong>argon2</strong> hash functions.</p>
<p>For both of these hash functions, there are online tools available to compute
hashes like <a rel="nofollow" href="https://bcrypt.online/">bcrypt.online</a> and
<a rel="nofollow" href="https://argon2.online/">argon2.online</a>.</p>
<p>Update 2022-09-28: Keyoxide now also has online tools to compute hashes:
<a rel="nofollow" href="https://keyoxide.org/util/bcrypt">Keyoxide bcrypt tool</a> and
<a rel="nofollow" href="https://keyoxide.org/util/argon2">Keyoxide Argon2 tool</a>.</p>
<p>The default parameters on these online tools are good enough for this purpose.
You may opt to increase the cost factor but don't go too high, it will take
longer to verify the hash and may result in a failed verification! For example,
for bcrypt, don't pick a cost factor above 12.</p>
<h2 id="Conclusion">Conclusion</h2>
<p>I hope this new feature will be of benefit to those seeking privacy protection.
As always, the communication channels are open for suggestions to improve the
hashing or supporting more algorithms.</p>
<p>Until next time,
Yarmo</p>
New NLnet grant!2022-09-12T13:38:52+00:002022-09-12T13:38:52+00:00
Unknown
https://blog.keyoxide.org/nlnet-2/<h2 id="Keyoxide_v2!">Keyoxide v2!</h2>
<p>It's been a while since the last update but work has not stopped. And now, I am
so very excited to announce that NLnet has awarded Keyoxide a <a rel="nofollow" href="https://nlnet.nl/project/Keyoxide-signatures/index.html">second
grant</a> to further
advance the various endeavours in which the Keyoxide project is involved.</p>
<p>The global focus of this new period of intensified development will be making it
easier for people to create and maintain their Keyoxide profiles. Much effort
will go into improving the support for a new type of profile — the so-called
<strong>signature profile</strong> — which one will be able to create using almost any of the
existing GnuPG tools out there. No more requiring people to interact with the
command line when they don't feel comfortable doing so.</p>
<p>Another point of focus will be <strong>chat platforms</strong>. The impact of impersonation
can be particularly severe on platforms where people interact with each other
directly. Keyoxide should thus be able to verify online identities on the major
communication platforms — provided the platform gives developers sufficient
access to do so.</p>
<p>Finally, this year will be all about documentation and specs. The Keyoxide
<strong>documentation</strong> can be much improved, both in terms of content and
accessibility. And the <strong>Ariadne Spec</strong> will get a do-over now that I have
realized the first iteration was attempting to accomplish way, way too much. A
more concise, to-the-point version will serve client implementations much better
— my own, and hopefully new ones developed by the community!</p>
<p>This coming period of development should make Keyoxide more stable and more
user-friendly for people in need of online inter-personal identification and
whom may not have the technical skills currently required to interact with
Keyoxide. This I have wanted for Keyoxide since the beginning and I
wholeheartedly thank the <a rel="nofollow" href="https://nlnet.nl">NLnet foundation</a> and the <a rel="nofollow" href="https://www.ngi.eu">NGI
initiative</a> for enabling me to accomplish this.</p>
<h2 id="New_documentation">New documentation</h2>
<p>To get started off on the right foot, let's actually look at some progress made
during the last couple of weeks.</p>
<p>First, let's also take a moment to be overly honest here: I didn't like the old
documentation. I didn't like the content of the guides nor the way the articles
were structured. Both issues have been dealt with in the latest <a rel="nofollow" href="https://docs.keyoxide.org">Keyoxide
docs</a>. I have rewritten parts or entire guides and
moved sections around to paint a clearer picture.</p>
<p>As an added bonus — and this really shouldn't be a bonus, this should be standard: the
documentation can now be translated in different languages! If you feel like
contributing by helping translate some of the guides, feel free to <a rel="nofollow" href="https://docs.keyoxide.org/community">reach out to
the community</a>, we can help you get set up.</p>
<p>A lot still needs to happen on the documentation site but it's getting
somewhere!</p>
<h2 id="HTTP_Proofs_(and_aliases)">HTTP Proofs (and aliases)</h2>
<p>Another potentially huge improvement is the new HTTP proof! Instead of adding a
cryptographic fingerprint to your biography — sure to make most people scratch
their head! — add the URL to your Keyoxide profile instead!</p>
<pre style="background-color:#f9f9f9;color:#111111;"><code><span>Hi! I'm Yarmo! This is my account on some website.
</span><span>My online identity is managed on https://keyoxide.org/yarmo@yarmo.eu
</span></code></pre>
<p>This snippet would actually result in a verified identity claim on Keyoxide 🤯</p>
<p>For the curious: it works using an HTTP response header! More info in the <a rel="nofollow" href="https://docs.keyoxide.org/proof-formats">proof
formats documentation</a>.</p>
<p>But why stop there? If I forward a path on my personal domain to my Keyoxide
profile, I can just use that as a valid proof.</p>
<pre style="background-color:#f9f9f9;color:#111111;"><code><span>Verifying my identity: https://yarmo.eu/id
</span></code></pre>
<p>That's both much shorter and more helpful than a cryptographic fingerprint!</p>
<p>Of course, everything mentioned above works on
<a rel="nofollow" href="https://keyoxide.org">keyoxide.org</a> but also any selfhosted instance.
Decentralization for the win 🚀</p>
<h2 id="Some_things_never_change">Some things never change</h2>
<p>Most important of all, the <a rel="nofollow" href="https://docs.keyoxide.org/community">community</a> is
still here 🤗 on the forum, the IRC channel, the Matrix room… Besides the
increasingly interesting discussions, there have also been contributions coming
in like the recently added support for account verification on <strong>Telegram</strong> and
<strong>Stack Exchange sites</strong> — thank you again,
<a rel="nofollow" href="https://codeberg.org/keyoxide/doipjs/pulls/24">Goldstein</a> and
<a rel="nofollow" href="https://codeberg.org/keyoxide/doipjs/pulls/23">cherryblossom</a>!</p>
<p>Here's to lots more improvements!</p>
<p>Until later,<br />
Yarmo</p>
In development: doip-rs2021-11-13T16:00:01+00:002021-11-13T16:00:01+00:00
Unknown
https://blog.keyoxide.org/doip-rust/<h2 id="A_DOIP_Rust_library">A DOIP Rust library</h2>
<p>I'd like to introduce <a rel="nofollow" href="https://codeberg.org/keyoxide/doip-rs">doip-rs</a>, a Rust library to interact with decentralized OpenPGP identity claims and proofs.</p>
<p>The way the library works is:</p>
<ul>
<li>you give it a claim and a fingerprint (see <strong>Usage</strong> below);</li>
<li>it tries to figure out what kind of claim it is (Twitter? Gitea? Owncast?);</li>
<li>it tries to fetch a proof at a predefined location;</li>
<li>it tries to find the fingerprint inside the proof;</li>
<li>if found, the claim is considered verified.</li>
</ul>
<p>It's not on <a rel="nofollow" href="https://crates.io">crates.io</a> yet, I'd like to smooth out the rough edges first.</p>
<p>It's licensed under <a rel="nofollow" href="https://codeberg.org/keyoxide/doip-rs/src/branch/main/LICENSE">Apache Version 2.0</a>.</p>
<h2 id="Usage">Usage</h2>
<p>Using the library is quite simple:</p>
<pre data-lang="rust" style="background-color:#f9f9f9;color:#111111;" class="language-rust "><code class="language-rust" data-lang="rust"><span style="color:#8959a8;">use </span><span>doip::claim::Claim;
</span><span style="color:#8959a8;">use </span><span>doip::service_provider::ServiceProvider;
</span><span>
</span><span style="color:#8e908c;">// Prepare the identity claim
</span><span style="color:#8959a8;">let</span><span> uri </span><span style="color:#3e999f;">= </span><span style="color:#839c00;">"https://codeberg.org/yarmo/gitea_proof"</span><span>;
</span><span style="color:#8959a8;">let</span><span> fingerprint </span><span style="color:#3e999f;">= </span><span style="color:#839c00;">"9f0048ac0b23301e1f77e994909f6bd6f80f485d"</span><span>;
</span><span style="color:#8959a8;">let mut</span><span> claim </span><span style="color:#3e999f;">= </span><span>Claim::new(uri, fingerprint);
</span><span>
</span><span style="color:#8e908c;">// Find matching service providers
</span><span>claim.</span><span style="color:#4271ae;">find_match</span><span>();
</span><span>
</span><span style="color:#8e908c;">// Verify the claim
</span><span>claim.</span><span style="color:#4271ae;">verify</span><span>().await;
</span><span>
</span><span style="color:#8e908c;">// Print the result
</span><span>println!(</span><span style="color:#839c00;">"Claim: </span><span>{:?}</span><span style="color:#839c00;">"</span><span>, claim);
</span></code></pre>
<p>The example above actually works and will verify my <a rel="nofollow" href="https://codeberg.org">Codeberg.org</a> account!</p>
<h2 id="Roadmap">Roadmap</h2>
<ul>
<li>Improve code quality</li>
<li>Improve documentation</li>
<li>Add parallel processing of claims</li>
<li>Add processing of cryptographic keys (using <a rel="nofollow" href="https://sequoia-pgp.org/">Sequoia-PGP</a>)</li>
<li>Add processing of signature profiles</li>
<li>Add additional proof request protocols (DNS, IRC, XMPP…)</li>
<li>Publish to crates.io</li>
</ul>
<h2 id="doip-rs_and_doip-js">doip-rs and doip-js</h2>
<p>Right now, the <a rel="nofollow" href="https://codeberg.org/keyoxide/doipjs">doip-js (javascript/node)</a> is more feature-complete than <a rel="nofollow" href="https://codeberg.org/keyoxide/doip-rs">doip-rs (rust)</a> but with time, doip-rs will catch up.</p>
<p>It may even at some point be possible to retire doip-js and replace it with a WASM build of doip-rs!</p>
<h2 id="doip-rs_and_ariadne.id">doip-rs and ariadne.id</h2>
<p>Currently, the doip-rs library "inherits" all its knowledge of service providers (How to verify a Twitter account? And a Lichess account?) from the doip-js library but with time, doip-rs will become compliant with the <a rel="nofollow" href="https://ariadne.id">Ariadne Spec</a> as it matures, a project we <a href="/ariadne-spec/">recently announced</a> that will contain all this knowledge in a project-independent format in an effort to stimulate the development of community-made libraries and tools.</p>
<h2 id="Signing_off">Signing off</h2>
<p>I'm excited to be delving into Rust and use it to advance the Keyoxide project. If you see code that can be improved, don't hesitate to <a rel="nofollow" href="https://codeberg.org/keyoxide/doip-rs/issues">file an issue</a> or <a rel="nofollow" href="https://lists.sr.ht/~yarmo/keyoxide-devel">write to the mailing list</a>. Of course, all PRs are welcome :)</p>
<p>Until later,<br />
Yarmo</p>
Now on Android!2021-11-11T17:00:01+00:002021-11-11T17:00:01+00:00
Unknown
https://blog.keyoxide.org/now-on-android/<h2 id="The_Keyoxide_Android_client_app">The Keyoxide Android client app</h2>
<p>I'm very excited to announce there's now an Android client app for Keyoxide! </p>
<p>Just like the website, it can view Keyoxide profiles and display the verification of identity claims! But now in a more mobile-friendly way :)</p>
<p>It's still a work-in-progress and doesn't do everything yet (see <strong>Roadmap</strong>) but it's a good start to another way of interacting with decentralized identities.</p>
<p>A huge huge thanks to <a rel="nofollow" href="https://fosstodon.org/@berker">@berker</a> without whom none of this would exist, he wrote the entire project in four weeks!</p>
<h2 id="A_Flutter_project">A Flutter project</h2>
<p>The <a rel="nofollow" href="https://codeberg.org/keyoxide/keyoxide-flutter">source code</a> for this project was written using the <a rel="nofollow" href="https://flutter.dev/">Flutter</a> toolkit which means that if there's demand for it, the app could also be generated for iOS devices. Do let us know if you'd like to see an iOS app happen:</p>
<ul>
<li>on the fediverse: <a rel="nofollow" href="https://fosstodon.org/@keyoxide">@keyoxide.org@fosstodon.org</a></li>
<li>on the matrix network: <a rel="nofollow" href="https://matrix.to/#/#keyoxide:matrix.org">#keyoxide:matrix.org</a></li>
<li>on the issue tracker: <a rel="nofollow" href="https://codeberg.org/keyoxide/keyoxide-flutter/issues">codeberg.org/keyoxide/keyoxide-flutter</a></li>
<li>via email: <a href="mailto:yarmo@keyoxide.org">yarmo@keyoxide.org</a></li>
</ul>
<h2 id="Roadmap">Roadmap</h2>
<p>There are a few things we are considering or working on that would be useful additions to the app:</p>
<ul>
<li>Open app when 3rd party QR reader app scans an OpenPGP QR code</li>
<li>Integrate QR reader in app</li>
<li>Add message encryption and signature verification</li>
<li>Support fully local claim verification</li>
</ul>
<h2 id="Antiroadmap">Antiroadmap</h2>
<p>What this app is not intended to be: an OpenPGP client or key management app. We know that editing keys and adding notations is still a complex procedure and would love nothing more than to have a simple app that handles all this for you in an easy-to-use package.</p>
<p>This app will do what the website can and so in a mobile-friendly way, but nothing more. For the safety of all our secret keys.</p>
<p>That doesn't mean we aren't having discussions around ideas on how to design and implement a secure key/identity management app. If you're interested and perhaps willing to help in this domain, be sure to join the matrix channel or start/join a discussion on the <a rel="nofollow" href="https://lists.sr.ht/~yarmo/keyoxide-devel">keyoxide-devel mailing list</a>.</p>
<h2 id="Download">Download</h2>
<p>Here's the <a rel="nofollow" href="https://codeberg.org/attachments/8714ab36-118b-48e3-97a6-fbc0e8ba7fc8">APK link</a> (<a rel="nofollow" href="https://codeberg.org/keyoxide/keyoxide-flutter/releases/tag/1.0.1">release 1.0.1</a>).</p>
<p>The app is currently going through the <a rel="nofollow" href="https://f-droid.org/">F-Droid</a> inclusion process and will hopefully be available on there soon! We're still on the fence about the benefits of putting the app on the Play Store. Again, feel free join the discussion and voice your opinion :)</p>
<h2 id="Signing_off">Signing off</h2>
<p>Another big thank you to <a rel="nofollow" href="https://fosstodon.org/@berker">@berker</a> for the amount of work and dedication you put into this project in such short time. Cheers mate!</p>
<p>Hope you all enjoy the app and be sure to catch some sun if you get the chance to!</p>
<p>Until later,<br />
Yarmo</p>
Keyoxide documentation update2021-11-07T20:43:32+00:002021-11-07T20:43:32+00:00
Unknown
https://blog.keyoxide.org/keyoxide-documentation-update/<p>Today is a big day for documentation.</p>
<h2 id="A_separate_space_for_docs">A separate space for docs</h2>
<p>The Keyoxide documentation is now on its own subdomain: <a rel="nofollow" href="https://docs.keyoxide.org">docs.keyoxide.org</a>.</p>
<p>It now also has a separate source repository: <a rel="nofollow" href="https://codeberg.org/keyoxide/keyoxide-docs">codeberg.org/keyoxide/keyoxide-docs</a>.</p>
<p>Both of these updates will make it easier to keep the docs up to date and even expand on it, adding more general-purpose guides and knowledge.</p>
<h2 id="The_Ariadne_Spec">The Ariadne Spec</h2>
<p>The highlight of today's update is the launch of the Ariadne Spec, an announcement so big it got its own <a href="/ariadne-spec/">blog post</a>!</p>
<p>It also has an entry in the <a rel="nofollow" href="https://docs.keyoxide.org/getting-started/what-is-ariadne-id/">new docs</a>.</p>
<p>The short version: the Ariadne Spec is an experimental community-driven living document that makes it easier to collectively improve the process that powers Keyoxide as well as start new independent implementations, libraries, apps and websites</p>
<p>An added benefit is that from now on, the OpenPGP notations will look like this:</p>
<pre style="background-color:#f9f9f9;color:#111111;"><code><span>proof@ariadne.id=https://someservice.tld/user
</span></code></pre>
<p>Have a look at the <a href="/ariadne-spec/">blog post</a> and <a rel="nofollow" href="https://docs.keyoxide.org/getting-started/what-is-ariadne-id/">docs entry</a> for more detailed information.</p>
<h2 id="Signing_off">Signing off</h2>
<p>Thanks for tuning in today, I'm really happy with the current progress of the project. It took a few months but we now have separate docs ready for improvement and a democratic process to collectively write a document that could benefit many. Let's hope it accomplishes its goal!</p>
<p>Two announcements down, two more to go :)</p>
<p>Talk to you again in a few days,<br />
Yarmo</p>
Launching the Ariadne Spec2021-11-07T19:54:45+00:002021-11-07T19:54:45+00:00
Unknown
https://blog.keyoxide.org/ariadne-spec/<p>TLDR: the Ariadne Spec is an experimental community-driven living document on cryptographic decentralized identity verification.</p>
<h2 id="The_abstraction_of_an_abstraction">The abstraction of an abstraction</h2>
<p>From the get-go, Keyoxide was designed to be about the process of identity verification, not about itself. And if you want to create an open ecosystem, you've got to make it welcoming.</p>
<p>So, not soon after launching Keyoxide, we extracted the identity verification code and released it as a separate library named <a rel="nofollow" href="https://codeberg.org/keyoxide/doipjs">doip.js</a> to make it easier for other websites and apps to start using OpenPGP identity proofs too—without having to rely on Keyoxide.</p>
<p>But even with a website-agnostic library, it didn't feel abstract enough: projects still would need to use our library, with our code design choices, written in a language of our choice.</p>
<p>Why not publish the essence of the decentralized identity verification process? Not the code, but the underlying knowledge.</p>
<h2 id="The_Ariadne_Spec">The Ariadne Spec</h2>
<p>That is the aim of the experimental Ariadne Spec, available at <a rel="nofollow" href="https://ariadne.id">https://ariadne.id</a>.</p>
<p>From the <a rel="nofollow" href="https://docs.keyoxide.org/getting-started/what-is-ariadne-id/">Keyoxide documentation</a>:</p>
<blockquote>
<p>The Ariadne Spec is our attempt to:</p>
<ul>
<li>create a community-driven living document that explains how decentralized online identities should work, and</li>
<li>create an ecosystem of code and apps that no single entity rules but everyone can benefit from.</li>
</ul>
<p>In short, it's a collection of text documents called ARCs that can be written by anyone willing to participate and are then democratically voted upon before being integrated into the Ariadne Spec. The ensemble of these ARCs is the Ariadne Spec(ification).</p>
<p>Since the Ariadne Spec's content is continuously subject to change, it's called a "living" document.</p>
<p>The Ariadne Spec is also "community-driven" because anyone can contribute, not just the people involved in the Keyoxide project.</p>
<p>This means that Keyoxide is really just an implementation of the Ariadne Spec: an actor in an ecosystem that could never be dominated by a single entity since the knowledge and its governance are open and accessible by all.</p>
<p>And that is just how we like our digital ecosystems.</p>
</blockquote>
<p>The entire ARC process is described in detail in <a rel="nofollow" href="https://ariadne.id/arc-0001.xml">ARC-0001</a>.</p>
<h2 id="proof@ariadne.id=">proof@ariadne.id=</h2>
<p>Given the fact that the knowledge on decentralized identity verification is now stored on its own domain, we can now use that domain as the new namespace for claim notations.</p>
<p>Or, in normal language, all claims will now look like this:</p>
<pre style="background-color:#f9f9f9;color:#111111;"><code><span>proof@ariadne.id=https://someservice.tld/user
</span></code></pre>
<p>A much requested feature since the beginning one year ago 🥳 but one which needed a lot of effort and thought to get right.</p>
<p>Oh, and all your "old" <code>proof@metacode.biz=</code> notations? No worries, they all still work and will always continue working!</p>
<h2 id="So_it's_all_working,_then?">So it's all working, then?</h2>
<p>Euhm, mostly.</p>
<p>We've decided to somewhat embrace the "release early, release often" paradigm on this one. The entire ARC process is still a little experimental and in progress. We've tried to adopt the best lessons and practices from processes like RFC and XEP and stick them in a low-barrier-to-entry implementation.</p>
<p>Mistakes will be made, but I believe in the collective know-how and determination of the people. Together, we are able to shape this process and democratically gather the knowledge needed to verify our online identities.</p>
<p>Even more important, this process must be fun. Plain, simple fun. Not enough of that going around in software development these days.</p>
<h2 id="Documentation-as-a-project">Documentation-as-a-project</h2>
<p>So, there it is. The <a rel="nofollow" href="https://ariadne.id">Ariadne Spec</a>. Our guide through the maze of online service providers and the diverse ways of proving our hold over our accounts on them. A path to claiming back sovereignty over our online identity.</p>
<p>A project that delivers documentation, not code.</p>
<p>Hope you like it. Hope it inspires some of you to go out there, log into your favorite online service, find a way to externally verify your hold over your account and share this knowledge through the Ariadne Spec.</p>
<p>Also hope it inspires some of you to start building additional librairies and projects based on this knowledge.</p>
<p>Yarmo</p>
Keyoxide blog is now live2021-11-04T14:52:10+00:002021-11-04T14:52:10+00:00
Unknown
https://blog.keyoxide.org/keyoxide-blog/<p>Hey there, welcome on the new dedicated Keyoxide blog!</p>
<p>It's a bit barebones—one might say <em>minimalist</em>—but it's a blog.</p>
<p>And statically generated.</p>
<p>Yes, I thought it was time to move Keyoxide announcements away from my <a rel="nofollow" href="https://yarmo.eu">personal blog</a> and give them their own space on the web.</p>
<h2 id="A_small_update">A small update</h2>
<p>The Keyoxide project has been silent lately, very silent in fact. But rest assured, the time was well spent, several subprojects were simultaneously demanding my attention and this led to all of them being somewhat delayed.</p>
<p>Upside of this: there will be multiple announcements in the coming days as all these separate efforts seem to near completion soon :)</p>
<p>Yarmo</p>
Keyoxide Project Update #52021-06-29T14:52:10+00:002021-06-29T14:52:10+00:00
Unknown
https://blog.keyoxide.org/keyoxide-project-update-5/<p>An update for all.</p>
<h2 id="Accessibility">Accessibility</h2>
<p>The latest 3.1.0 release of <a rel="nofollow" href="https://codeberg.org/keyoxide/keyoxide-web">keyoxide-web</a> greatly improves accessibility
and ensures that it works nicely together with screen readers.</p>
<p>To make sure the implementation of accessibility features was as thorough as possible, it was first ran through a series
of automated tests, namely <a rel="nofollow" href="https://web.dev/measure/">Lighthouse</a> and <a rel="nofollow" href="https://wave.webaim.org/">WAVE</a>, both giving
Keyoxide respectively a <strong>100% accessibility score</strong> and <strong>0 accessibility errors</strong> on every page.</p>
<p>While automated tests are a decent start, nothing beats feedback from the actual target audience: good ol' human beings.</p>
<p>After <a rel="nofollow" href="https://fosstodon.org/@keyoxide/106380848176122986">posting a message</a> on the Keyoxide fediverse account
(<a rel="nofollow" href="https://fosstodon.org/@keyoxide">keyoxide@fosstodon.org</a>) to call for help from people who use accessibility tools
like screen readers, I received plenty of feedback about little quirks that went undetected by the automated tests.
These were all addressed and fixed.</p>
<p>So I can now gladly confirm that the Keyoxide website should be <strong>WAI-AA</strong> compliant, meaning all text has a contrast
ratio higher than 4.5:1, all links and images are appropriately labeled for screen readers and even the profile pages
can be navigated by keyboard alone.</p>
<p>I once again thank the people that have provided the invaluable feedback without whom the result of my efforts would
have proven unsufficient.</p>
<p>If you find more quirks and/or annoyances, please do file an issue on the
<a rel="nofollow" href="https://codeberg.org/keyoxide/keyoxide-web/issues">code repository</a> so it can be fixed as quickly as possible.</p>
<h2 id="#keyoxide_on_IRC">#keyoxide on IRC</h2>
<p>Keyoxide was just about to request a channel on freenode when sadly, well, <em>that</em> happened.</p>
<p>So now, it is with delight that I can now invite you all to our <strong>#keyoxide</strong> channel on the great
<a rel="nofollow" href="https://libera.chat/">libera.chat</a> network. In addition to our Matrix room, this is one more place where we can hang
out and discuss the future of identity on the internet. And many other things.</p>
<p>And yes, of course I have already proven my identity on IRC using the
<a rel="nofollow" href="https://keyoxide.org/guides/irc">IRC guide on Keyoxide</a>.</p>
<h2 id="Signing_off">Signing off</h2>
<p>For all your questions and suggestions, be sure to join the conversation in the
<a rel="nofollow" href="https://matrix.to/#/#keyoxide:matrix.org">Keyoxide matrix room</a> or the #keyoxide channel on
<a rel="nofollow" href="https://libera.chat/">libera.chat</a>. Or raise an issue on <a rel="nofollow" href="https://codeberg.org/keyoxide/">Codeberg.org</a>.
All contributions (including PRs!) are welcome.</p>
<p>As always, the source code is available at the <a rel="nofollow" href="https://codeberg.org/keyoxide/keyoxide-web">Codeberg.org repo</a>.</p>
<p>All work on Keyoxide is possible thanks to donations, the project stands against VC funding. If you feel like Keyoxide
is a step in the right direction for netizens worldwide, please <a rel="nofollow" href="https://liberapay.com/Keyoxide/">become a patron</a> and
help the project do its part in the global fight against the internet corporations.</p>
<p>Until next time,<br />
Yarmo</p>
Keyoxide Project Update #42021-05-04T17:52:10+00:002021-05-04T17:52:10+00:00
Unknown
https://blog.keyoxide.org/keyoxide-project-update-4/<p>The update I have been looking forward to for months.</p>
<h2 id="Keyoxide_3.0.0">Keyoxide 3.0.0</h2>
<p>Every day I work on Keyoxide, I learn more and gain a deeper understanding of how powerful this Decentralized
OpenPGP-based Identity verification actually can be. And as we are nearing the first anniversary of the Keyoxide project,
I realized all the new ideas and major improvements—most suggested by the community—were being held back by
the previous implementation of the code, restricted by my earlier understanding and imagination.</p>
<p>It was time not for a number of superficial additions and fixes, but for a big overhaul of the core code which would
then cause a chain reaction of bugs to be fixed and features to be added or improved.</p>
<p>To illustrate what is new in this version, here's my
<a rel="nofollow" href="https://keyoxide.org/9f0048ac0b23301e1f77e994909f6bd6f80f485d">Keyoxide profile</a>.</p>
<h3 id="Visuals">Visuals</h3>
<p>Ok, let's do start superficial, though. Keyoxide 3.0.0 has a shiny new look. I hope you will agree with me that that
was much needed. The previous design of the website was made before I even implemented the concept of decentralized
proofs.</p>
<p>The new and cleaner design has eliminated most of the clutter and puts all the emphasis on what is important: the
identity claims.</p>
<h3 id="Server_side_rendering">Server side rendering</h3>
<p>Thanks to the class-based approach of the <a rel="nofollow" href="https://codeberg.org/keyoxide/doipjs/">doip.js library (version 0.12.*)</a>,
Keyoxide will now do most of the mundane work on the server and let the browser finish the process of identity
verification. So who does exactly what now?</p>
<ul>
<li>The server will try and find the public key associated with the profile to be generated</li>
<li>The server will parse the identity claims stored inside the public key</li>
<li>The server will match the identity claims to the known library of service providers</li>
<li>The server will render the profile page, including the yet-to-be-verified identity claims, and send it to the browser</li>
<li>The browser will parse the yet-to-be-verified identity claims and verify them</li>
</ul>
<p>Not only is the website now much faster to load, the browser will verify the identity claims in parallel! No more
waiting for that one slow identity to verify before showing the result of all the other identity verifications.</p>
<h3 id="rel="me"">rel="me"</h3>
<p>The wait is finally over! Server-side rendering means that Mastodon instances can now detect the <strong>rel="me"</strong> links
on Keyoxide profile pages and will reward you with a green tick for every Keyoxide profile you link to in your
Mastodon bio!</p>
<p>Here's an example: <a rel="nofollow" href="https://fosstodon.org/@keyoxide">@keyoxide@fosstodon.org</a>. So satisfying!</p>
<p>Yes, this means Keyoxide can now do and be as much as "any other" identity provider on Mastodon. By just using basic
web technology. Without requiring special server protocols. And no VC-funded companies needed.</p>
<p>Small web truly is beautiful, isn't it? (quote from <a rel="nofollow" href="https://small-tech.org/">Small Tech Foundation</a>)</p>
<h3 id="A_claim_failed,_what_does_that_mean?">A claim failed, what does that mean?</h3>
<p>The issue of a claim failing to verify is actually more complex than it seems, and something that the previous versions
of Keyoxide did not handle very elegantly.</p>
<p>As an example, let us claim to be Alice on Github. If it fails, it could either mean that we made a mistake somewhere,
or we are attempting to impersonate Alice—the very thing Keyoxide is designed to detect and prevent.</p>
<p>In this case, it's simple: the claim <code>https://gist.github.com/Alice/...</code> could only reference Github so the story ends
here.</p>
<p>But what if we wanted to verify <code>https://alice.tld/apps/live</code>? From the looks of it, it could be an
<a rel="nofollow" href="https://owncast.online/">Owncast</a> server, but that is just a guess.</p>
<p>When this claims fails to verify, does it fail because that Owncast server is not mine (impersonation) or because it
wasn't actually an Owncast server? This URL could also very well lead to a repo on a <a rel="nofollow" href="https://gitea.io/">Gitea</a> server.</p>
<p>And what if it also fails to verify as a Gitea account? Was it one of them that genuinely failed, or neither of them?</p>
<p>Keyoxide 3.0.0 now recognizes "ambiguity" in URLs and acts accordingly. Does a claim with an unambiguous URL (like
Github) fail? Keyoxide will let the visitor know the claim genuinely failed. Did a claim with an ambiguous URL fail?
Then Keyoxide will show a message letting the visitor know that it wasn't sure what the claim was meant to be but
regardless, it failed to verify.</p>
<h2 id="Future_improvements">Future improvements</h2>
<p>Keyoxide 3.0.0 brings a few tweaks, but again, the biggest change is the overhaul of the core code. This will allow
a bunch more improvements to be made soon with relative ease. Here's an overview of what is in the pipeline.</p>
<h3 id="Requirement_of_JavaScript">Requirement of JavaScript</h3>
<p>Previous versions of Keyoxide said "the browser must do everything". This meant that JavaScript had to enabled in order
for Keyoxide to be able to do anything at all.</p>
<p>As stated above, Keyoxide 3.0.0 now only lets the browser do the very last step of the whole process but this still
means JavaScript is required. However, it is not difficult to imagine now that the server could do everything and just
send the finished profile page to the browser.</p>
<p>In a future version of Keyoxide, visitors who have JavaScript disabled and do not mind waiting for up to fifteen seconds
(due to some claims taking more time to verify) will be able to request a fully server-side rendered profile page.</p>
<h3 id="a11y_and_i18n">a11y and i18n</h3>
<p>With more work being done server-side, it becomes simpler to implement internationalisation and render the website in
different languages.</p>
<p>Also, with the pages themselves become less dynamic, decent accessibility is also simpler to achieve and currently has
the highest priority.</p>
<h2 id="Signing_off">Signing off</h2>
<p>That's about it for today. This update marks a big change that will greatly benefit future versions of Keyoxide. I can't
wait to start working on the next developments and share them with you as they come along.</p>
<p>As always, the source code is available at the <a rel="nofollow" href="https://codeberg.org/keyoxide/keyoxide-web">Codeberg.org repo</a>
(now renamed to <strong>keyoxide-web</strong>).</p>
<p>For all your questions and suggestions, be sure to join the conversation in the
<a rel="nofollow" href="https://matrix.to/#/#keyoxide:matrix.org">Keyoxide matrix room</a> or raise an issue on
<a rel="nofollow" href="https://codeberg.org/keyoxide/">Codeberg.org</a>. All contributions are welcome!</p>
<p>Until next time.</p>
Keyoxide Project Update #32021-03-09T16:00:00+00:002021-03-09T16:00:00+00:00
Unknown
https://blog.keyoxide.org/keyoxide-project-update-3/<p>Two months since the last update. Two great new additions for this one.</p>
<h2 id="Keyoxide_2.5.0">Keyoxide 2.5.0</h2>
<p>The latest version of Keyoxide's web client has two very neat additions, all
thanks to the latest <a rel="nofollow" href="https://codeberg.org/keyoxide/doipjs">0.11.*</a> release of
<a href="https://blog.keyoxide.org/keyoxide-project-update-3/js.doip.rocks">doip.js</a>: the verification of accounts on the IRC and Matrix
platforms.</p>
<p>This really is what Keyoxide was designed to do: making sure your online
correspondances are exchanged with the intended person or entity, even as both
parties use anonymous accounts with varying usernames on different platforms.</p>
<p>To this end, it was important to integrate additional communication platforms,
to join the already supported <a rel="nofollow" href="https://keyoxide.org/guides/xmpp">XMPP</a> protocol.</p>
<p>Given the popularity and decentralized nature of either platform, IRC and Matrix
were both prime candidates. So, let's see what goes into proving identities on
IRC and Matrix.</p>
<p>(All examples below use a certain OpenPGP fingerprint and a fictional user, make
sure to use your own data when replicating the steps!)</p>
<h2 id="Proving_IRC_identity_with_taxonomy">Proving IRC identity with taxonomy</h2>
<p>What is taxonomy within the context of IRC?</p>
<pre style="background-color:#f9f9f9;color:#111111;"><code><span>>> /msg NickServ help TAXONOMY
</span><span>
</span><span>***** NickServ Help *****
</span><span>Help for TAXONOMY:
</span><span>
</span><span>The taxonomy command lists metadata information associated
</span><span>with registered users.
</span><span>
</span><span>Examples:
</span><span> /msg NickServ TAXONOMY foo
</span><span>***** End of Help *****
</span></code></pre>
<p>Taxonomy is metadata information, much like the vCard data for XMPP. Let us use
this to our advantage:</p>
<pre style="background-color:#f9f9f9;color:#111111;"><code><span>>> /msg NickServ SET PROPERTY KEY openpgp4fpr:3637202523e7c1309ab79e99ef2dc5827b445f4b
</span><span>
</span><span>Metadata entry KEY added.
</span><span>
</span><span>>> /msg NickServ TAXONOMY foo
</span><span>
</span><span>Taxonomy for foo:
</span><span>KEY : openpgp4fpr:3637202523e7c1309ab79e99ef2dc5827b445f4b
</span><span>End of foo taxonomy.
</span></code></pre>
<p>And there you have it: one-directional linking from IRC to an OpenPGP key. Now,
to make that bidirectional, add the following notation to your key:</p>
<pre style="background-color:#f9f9f9;color:#111111;"><code><span>proof@metacode.biz=irc://chat.freenode.net/foo
</span></code></pre>
<p>Et voilà, foo has now cryptographically proven that that IRC nickname is theirs.</p>
<p>All steps above are explained with more detail in the
<a rel="nofollow" href="https://keyoxide.org/guides/irc">IRC guide</a>.</p>
<p>It is important to note that IRC is the slowest identity to verify to date. As
IRC servers lack API endpoints to query the taxonomy metadata (maybe one
day? ^_^), Keyoxide has to log in into the IRC server like any other client,
send a message to NickServ, parse the response and log out again.</p>
<h2 id="Proving_Matrix_identity_with...">Proving Matrix identity with...</h2>
<p><a rel="nofollow" href="https://matrix.org/">Matrix</a> is an excellent decentralized communication
platform, but sadly, for identity verification purposes, it completely lacks
any form of customisable metadata. A shortcoming we can work with, but one which
might also understandibly deter some from proving Matrix identities.</p>
<p>One simply sends a message to a public room with the following content:</p>
<pre style="background-color:#f9f9f9;color:#111111;"><code><span>[Verifying my OpenPGP key: openpgp4fpr:3637202523e7c1309ab79e99ef2dc5827b445f4b]
</span></code></pre>
<p>Easy enough. The issue is: Keyoxide can only read messages in a public room via
a Matrix account that already has access to said public room.</p>
<p>Ergo, we can't just use any room, we'll all have to use the same room.</p>
<p>A dedicated room named
<a rel="nofollow" href="https://matrix.to/#/#doipver:matrix.org">#doipver:matrix.org</a> has been created
for the very purpose of receiving Matrix identity proofs. Simply join the room
and send the message with your own OpenPGP fingerprint.</p>
<p>By viewing the source of message, you get the data needed to generate the
identity claim to be stored inside your OpenPGP key: the <code>room_id</code> (shared by
everyone) and the <code>event_id</code> (unique to your proof). The notation will look
like this:</p>
<pre style="background-color:#f9f9f9;color:#111111;"><code><span>proof@metacode.biz=matrix:u/@foo:matrix.org?org.keyoxide.r=!dBfQZxCoGVmSTujfiv:matrix.org&org.keyoxide.e=$3dVX1nv3lmwnKxc0mgto_Sf-REVr45Z6G7LWLWal10w
</span></code></pre>
<p>That is quite an unwieldy notation, but one designed to follow the
<a rel="nofollow" href="https://github.com/matrix-org/matrix-doc/pull/2312">MSC2312 Matrix URI scheme proposal</a>
.</p>
<p>Please refer to the <a rel="nofollow" href="https://keyoxide.org/guides/matrix">Matrix guide</a> for
detailed instructions on how to verify your own Matrix identity.</p>
<h2 id="Signing_off">Signing off</h2>
<p>As the project now supports multiple communications platforms and its
versatility increases with each update, I am confident that Keyoxide is now
ready for the next phase: focus on the user experience. Nothing to show just
yet, but I am sure the next project update will have interesting announcements
related to this.</p>
<p>For all your questions and suggestions, be sure to join the conversation in the
<a rel="nofollow" href="https://matrix.to/#/#keyoxide:matrix.org">Keyoxide matrix room</a>.</p>
<p>Until next time.</p>
Keyoxide Project Update #22021-01-11T16:30:00+00:002021-01-11T16:30:00+00:00
Unknown
https://blog.keyoxide.org/keyoxide-project-update-2/<p>A prosperous 2021 to all. Let's dive into some Keyoxide news.</p>
<h2 id="Signature_profiles">Signature profiles</h2>
<p>The Keyoxide web client just got updated to <a rel="nofollow" href="https://codeberg.org/keyoxide/web/releases/tag/2.4.0">2.4.0</a> which
introduced a few minor bug fixes as well as a robots.txt and noindex meta tags.</p>
<p>The most exciting new feature in this release is the support for "signature profiles", a new way of creating
decentralized profiles that is both simpler to generate and solves a few drawbacks that come with the traditional
method of storing identity claims as notations in cryptographic keys.</p>
<p>From the newly added <a rel="nofollow" href="https://keyoxide.org/guides/signature-profiles">signature profiles guide</a>:</p>
<blockquote>
<p>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.</p>
<p>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.</p>
<p>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.</p>
<p>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!</p>
</blockquote>
<h3 id="What_does_a_signature_profile_look_like?">What does a signature profile look like?</h3>
<p>Here's an example:</p>
<pre style="background-color:#f9f9f9;color:#111111;"><code><span>-----BEGIN PGP SIGNED MESSAGE-----
</span><span>Hash: SHA512
</span><span>
</span><span>Hey there! Here's a signature profile with proofs related to the DOIP project (https://doip.rocks).
</span><span>
</span><span>Verify this profile at https://keyoxide.org/sig
</span><span>
</span><span>proof=dns:doip.rocks
</span><span>proof=https://fosstodon.org/@keyoxide
</span><span>-----BEGIN PGP SIGNATURE-----
</span><span>
</span><span>iQHEBAEBCgAuFiEENjcgJSPnwTCat56Z7y3FgntEX0sFAl/7L0MQHHRlc3RAZG9p
</span><span>cC5yb2NrcwAKCRDvLcWCe0RfS3iYC/0QQqz2lzSNrkApdIN9OJFfd/sP2qeGr/uH
</span><span>98YHa+ucwBxer6yrAaTYYuBJg1uyzdxQhqF2jWno7FwN4crnj15AN5XGemjpmqat
</span><span>py9wG6vCVjC81q/BWMIMZ7RJ/m8F8Kz556xHiU8KbqLNDqFVcT35/PhJsw71XVCI
</span><span>N3HgrgD7CY/vIsZ3WIH7mne3q9O7X4TJQtFoZZ/l9lKj7qk3LrSFnL6q+JxUr2Im
</span><span>xfYZKaSz6lmLf+vfPc59JuQtV1z0HSNDQkpKEjmLeIlc+ZNAdSQRjkfi+UDK7eKV
</span><span>KGOlkcslroJO6rT3ruqx9L3hHtrM8dKQFgtRSaofB51HCyhNzmipbBHnLnKQrcf6
</span><span>o8nn9OkP7F9NfbBE6xYIUCkgnv1lQbzeXsLLVuEKMW8bvZOmI7jTcthqnwzEIHj/
</span><span>G4p+zPGgO+6Pzuhn47fxH+QZ0KPA8o2vx0DvOkZT6HEqG+EqpIoC/a7wD68n789c
</span><span>K2NLCVb9oIGarPfhIdPV3QbrA5eXRRQ=
</span><span>=QyNy
</span><span>-----END PGP SIGNATURE-----
</span></code></pre>
<p>I only wrote the four lines after <code>Hash: SHA512</code>! The rest is generated by an OpenPGP-compatible library.</p>
<p>The first two lines are meant for humans. They state my intent with this signature profile as well as give an
instruction to whomever receives it.</p>
<p>The remaining two lines are my identity claims. They follow a specific syntax that Keyoxide and any other service using
<a rel="nofollow" href="https://doip.rocks">doip.js</a> can interpret.</p>
<p>The text around it is the signature. They make the message both provably beyond doubt written by yours truly, and
untemparable. Try it in the next step, change any character in the text, it will fail. This ensures that no bad actor
could intercept my signature on its way to you and modify its content.</p>
<h3 id="What_to_do_with_it?">What to do with it?</h3>
<p>When put into <a rel="nofollow" href="https://keyoxide.org/sig">keyoxide.org/sig</a>, the website will perform two verifications.</p>
<p>First, is the signature valid? Has the text been tampered with? If the signature is valid, a so-called 'fingerprint'
is extracted from it and displayed. Preferably, I have already mentioned my fingerprint to you. This ensures that you
didn't simply get a signature from someone else pretending to be me.</p>
<p>The fingerprint of the key that I used for the signature above is <code>3637202523e7c1309ab79e99ef2dc5827b445f4b</code>.</p>
<p>Second step is the verification of the identity claims. I could write a perfectly valid signature profile filled with
absurd and incorrect identity claims! We don't want that.</p>
<p>The fingerprint we just extracted from the signature is now used to verify these identity claims. For example, the first
claim (doip.rocks) will have a DNS record with that value. And the second claim (fosstodon.org/@keyoxide) has the
fingerprint in the bio section of the account.</p>
<p>Both should verify. This allows you to say:</p>
<blockquote>
<p>Whoever signed this profile, holds the doip.rocks domain name and the fosstodon.org/@keyoxide account.</p>
</blockquote>
<h3 id="Granular_and_non-scrapable_identity_claims">Granular and non-scrapable identity claims</h3>
<p>There you have it. Identity claims that can be sent granularly (you pick and choose which to include) and are
non-scrapable (signature profiles are not publicly available).</p>
<p>And if you wish to go a step further, you can even encrypt the signature profile to make sure it can't be read while in
transit to the intended recipient.</p>
<p>Happy signing!</p>
<h2 id="doip.js_0.9.0">doip.js 0.9.0</h2>
<p><a rel="nofollow" href="https://codeberg.org/keyoxide/doipjs/releases/tag/0.9.0">Release 0.9.0</a> of <a rel="nofollow" href="https://js.doip.rocks">doip.js</a> introduced
support for the verification of signature profiles. In fact, Keyoxide simply relies on doip.js for all identity
verifications. This makes it possible for new projects to get started quickly with fully decentralized identity
verification and always have the same feature set that Keyoxide has.</p>
<p>This is the way.</p>
<h2 id="Signing_off">Signing off</h2>
<p>Hope you enjoy the signature profiles. Do not hesitate to get in touch for questions, comments or suggestions. There's
a <a rel="nofollow" href="https://matrix.to/#/#keyoxide:matrix.org">Keyoxide matrix room</a> as well as a
<a rel="nofollow" href="https://lists.sr.ht/~yarmo/keyoxide-devel">mailing list</a>.</p>
<p>Until next time.</p>
Keyoxide CLI released2020-12-08T16:30:00+00:002020-12-08T16:30:00+00:00
Unknown
https://blog.keyoxide.org/keyoxide-cli-released/<p>Five months ago when I made <a rel="nofollow" href="https://keyoxide.org">keyoxide.org</a> public, one
specific request made by quite a few people stood out: we need the ability to
perform the identity verification locally. And given that it was a quite
technical crowd, this meant: we need a command-line interface (CLI).</p>
<h2 id="The_command-line_interface">The command-line interface</h2>
<p>Today, I'm pleased to announce the release of the CLI. Written in Node.js and
published on <a rel="nofollow" href="https://codeberg.org/keyoxide/cli">Codeberg</a> under the
<a rel="nofollow" href="https://codeberg.org/keyoxide/cli/src/branch/main/LICENSE">AGPL-v3.0-or-later</a>
license, the Keyoxide CLI uses the recently released
<a rel="nofollow" href="https://js.doip.rocks">doip.js</a> library and does all the things the Keyoxide
website does, but locally. This means you no longer need to trust the website of
the Keyoxide instance you are using, its maintainer or everything inbetween.</p>
<p>Your machine fetches the keys, parses them locally and then directly requests
the identity proofs from the service providers to verify the identity
claims. Here's a quick tour.</p>
<p>Assuming you already have Node.js installed, first install the CLI:</p>
<pre data-lang="bash" style="background-color:#f9f9f9;color:#111111;" class="language-bash "><code class="language-bash" data-lang="bash"><span style="color:#c82728;">npm</span><span style="color:#4271ae;"> install</span><span style="color:#f07219;"> -g</span><span style="color:#4271ae;"> keyoxide
</span></code></pre>
<p>Then go and verify the identity proofs inside a cryptographic key! To get
started, try out the key I use for testing:</p>
<pre data-lang="bash" style="background-color:#f9f9f9;color:#111111;" class="language-bash "><code class="language-bash" data-lang="bash"><span style="color:#c82728;">keyoxide</span><span style="color:#4271ae;"> verify hkp:test@doip.rocks
</span></code></pre>
<p>You should now get the following result:</p>
<pre style="background-color:#f9f9f9;color:#111111;"><code><span>Verification results:
</span><span>Yarmo Mackenbach (material for test frameworks) <test@doip.rocks>
</span><span> ✓ doip.rocks (dns)
</span></code></pre>
<p>And there you have it! Whoever generated this key verifiably owns the
<a rel="nofollow" href="https://doip.rocks">doip.rocks</a> domain name.</p>
<p>Of course, the CLI can also fetch keys using WKD or get them from Keybase. More
information about these protocols is available on the
<a rel="nofollow" href="https://keyoxide.org/">Keyoxide</a> website and in the source code's
<a rel="nofollow" href="https://codeberg.org/keyoxide/cli">readme</a> document.</p>
<h2 id="FOSS_FTW">FOSS FTW</h2>
<p>As always, this project is fully open source and I welcome all criticism and
contributions, both issues and PRs. We all stand to benefit from solutions that
are built for and by the people. As governments worldwide push for cryptographic
backdoors, let us all keep using and promote free and open software.</p>
<p>Many thanks to <a rel="nofollow" href="https://nlnet.nl">NLnet</a> for supporting me on this journey and
allowing me to focus on these projects while keeping them free from VC funding
and other means of monetization that could compromise the privacy of the
individual.</p>
<p>If you value my efforts and would like to donate, it's possible to do so on the
project's <a rel="nofollow" href="https://liberapay.com/Keyoxide/">Liberapay</a> page. Cheers and I'll see
you in the next Keyoxide project update post!</p>
Keyoxide Project Update #12020-11-09T14:00:00+00:002020-11-09T14:00:00+00:00
Unknown
https://blog.keyoxide.org/keyoxide-project-update-1/<p>Time for the first big Keyoxide project update! A lot to cover, so let's get to
it.</p>
<h2 id="The_Big_Identity">The Big Identity</h2>
<p>Decentralized identity is coming. <a rel="nofollow" href="https://www.w3.org/TR/did-core/">DIDs</a> are
coming. Awesome libraries like <a rel="nofollow" href="https://idx.xyz/">IDX</a> are being published. Even
<a rel="nofollow" href="https://www.microsoft.com/en-us/security/business/identity/own-your-identity">Microsoft</a>
seems on board.</p>
<p>My point is this: decentralized identity is an exciting field to be working on
right now and I'm committed to keep learning about this domain, its technologies
and contribute to our digital society's cure from the parasitic tech giants.
Keyoxide and the response it generated showed me this is within the realm of the
possible.</p>
<h2 id="A_wild_foundation_appears!">A wild foundation appears!</h2>
<p>To help me achieve this, I've decided to set up a foundation. Please welcome the
<a rel="nofollow" href="https://keytoidentity.foundation">Key to Identity Foundation</a>! The foundation
will serve as an umbrella for a couple of identity-related projects to come,
which I will be glad to share more about as they progress. In fact, one of these
new projects is included in this update :)</p>
<p>Having a non-profit foundation also allows me to try and fully sustain the
project on donations and grants. I truly believe this model will help the
project and give it the best chance at making a significant change out there.</p>
<p>And as it turns out, I am not the only one who wants to see that happen…</p>
<h2 id="NLnet_grant_for_Keyoxide_development">NLnet grant for Keyoxide development</h2>
<p>The awesome people over at <a rel="nofollow" href="https://nlnet.nl/">NLnet</a> have taken a good look at
the current status of the Keyoxide project, my plans for its future and it is
now my pleasure to announce they have decided to award me an
<a rel="nofollow" href="https://nlnet.nl/NGI0/">NGI Zero grant</a> and fund the development!</p>
<p>I couldn't be more excited about this news. Keyoxide generated a lot of positive
feedback and ideas on how to improve it when it launched. Getting the
possibility to work on it full-time and build on the aspects that were important
to the community is a dream come true.</p>
<p>More information available on the
<a rel="nofollow" href="https://nlnet.nl/project/Keyoxide/">NLnet website</a>.</p>
<h2 id="Keyoxide_endgame">Keyoxide endgame</h2>
<p>I would like to expand on a point that is dear to me. Today's internet is in its
precarious state because we put faith in monopolistic forces that blossomed
under a lack of competition. The endgame of this endeavor is not just to create
a successful project. It is to build an ecosystem that will thrive on
competition and ultimately deliver the best experience for netizens.</p>
<p>It is what this in mind that I am releasing a new project today that should help
new projects get started in the decentralized identity world.</p>
<h2 id="doip.js">doip.js</h2>
<p><strong>DOIP</strong> stands for Decentralized OpenPGP Identity Proofs, the technology that
enables the identity verification that Keyoxide performs.</p>
<p><strong>doip.js</strong> is a Node.js library that enables any project to perform the same
tricks. It is even able to run directly in the browser!</p>
<p>What excites me most is that any contribution, like supporting new service
providers, is immediately available to all those projects and websites, not just
Keyoxide.</p>
<p>Documentation is available at <a rel="nofollow" href="https://js.doip.rocks/#/">doip.rocks</a>.</p>
<p>Code is licensed under Apache 2.0 and hosted by
<a rel="nofollow" href="https://codeberg.org/keyoxide/doipjs">Codeberg.org</a>.</p>
<h2 id="Building_a_community">Building a community</h2>
<p>Keyoxide now has a Matrix room, come hang out and discuss related topics!</p>
<p>Invite link: <a rel="nofollow" href="https://matrix.to/#/#keyoxide:matrix.org">#keyoxide:matrix.org</a></p>
<h2 id="The_road_ahead">The road ahead</h2>
<p>We are just getting started here. A lot still needs to happen to make Keyoxide
and OpenPGP-based decentralized identity practical and useful for a larger
audience. With the NLnet grant and my newly-acquired ability to turn this
project into a full-time job, I foresee a bright future.</p>
<p>Hope to see you back for the next update!</p>
Keyoxide 1.0.0: switched to AGPL-v32020-07-30T12:48:24+00:002020-07-30T12:48:24+00:00
Unknown
https://blog.keyoxide.org/keyoxide-agpl/<h2 id="The_big_1.0.0">The big 1.0.0</h2>
<p>Well, yes but no. It's actually a small update but with a MAJOR (get it? Because <a rel="nofollow" href="https://semver.org/">semver</a>) change: the project has switched to the <a rel="nofollow" href="https://www.gnu.org/licenses/agpl-3.0.en.html">AGPL-3.0-or-later</a> license.</p>
<p>When I started the <a rel="nofollow" href="https://keyoxide.org">Keyoxide</a> project, it didn't have the scope and ambitions it has now. What begun as a tool to bring simple PGP operations directly to the user's browser—a side project like many others—has turned into a full-blown solution to prove online identity in a decentralized manner.</p>
<p>The project has also seen quite a warm welcome among the tech-savvy and privacy-minded as a partial replacement for alternatives like Keybase. More importantly, the project has started receiving contributions from other people. From that point on, as was pointed out to me by <a rel="nofollow" href="https://social.tchncs.de/@t0k">@t0k@social.tchncs.de</a>, a permissive license like I was using before will no longer do.</p>
<p>A copyleft license like <a rel="nofollow" href="https://www.gnu.org/licenses/agpl-3.0.en.html">AGPL-3.0-or-later</a> is much better suited to protect the project and its contributors from getting the source code—including everyone's contributions—turned into a closed-source clone. Keyoxide is for the online citizenry and will remain so.</p>
<h2 id="Why_1.0.0?">Why 1.0.0?</h2>
<p>Usually, the "big 1.0" is associated with a project coming out of a beta period or more generally, becoming a product that users can use without excessive bugs. This is not the case here.</p>
<p>The versioning of this project adheres to <a rel="nofollow" href="https://semver.org/">semver</a>: MAJOR-MINOR-PATCH. A license change such as this one might put certain people or organizations off from using it (it shouldn't… but it might) and could therefore be considered a breaking change which, according to semver, triggers a MAJOR release.</p>
<p>Hence 1.0.0.</p>
Keyoxide and XMPP + OMEMO2020-07-23T14:08:02+00:002020-07-23T14:08:02+00:00
Unknown
https://blog.keyoxide.org/keyoxide-xmpp-omemo/<h2 id="XMPP">XMPP</h2>
<p><a rel="nofollow" href="https://xmpp.org/">XMPP</a> is an open messaging protocol that not only drives a <strong>thriving secure communication ecosystem for the privacy-minded</strong>, but also handles the messages sent by platforms like WhatsApp and Zoom. Knowingly or not, you have most likely used XMPP at some point in your life.</p>
<p><em>For the rest of this post, we will not take into account services like WhatsApp and Zoom as their platforms are closed off from all other platforms even though they use the same XMPP protocol.</em></p>
<p>That <strong>ecosystem for the privacy-minded</strong> consists of libraries for developers, server applications for the tech-savvy service providers and clients like <a rel="nofollow" href="https://dino.im/">Dino</a> (Linux), <a rel="nofollow" href="https://gajim.org/">Gajim</a> (Windows, Mac, Linux) and <a rel="nofollow" href="https://conversations.im/">Conversations</a> (Android) for everyone.</p>
<p>Because there is no single server or client to rule them all, we call this is a <em>decentralized</em> network. I could use a different server and a different client than you do, but we would still be able to communicate with each other. Also, any server or client could cease to exist the next day without impacting the rest of the network.</p>
<h2 id="Care_to_join_the_XMPP_ecosystem?">Care to join the XMPP ecosystem?</h2>
<p>Joining the XMPP ecosystem is as simple as making an account on a server and logging in using any XMPP-compatible client. But which server? Which client?</p>
<p>While not the focus of this post, here is a <a rel="nofollow" href="https://xmpp-servers.404.city/">list provided by 404.city</a> and a <a rel="nofollow" href="https://list.jabber.at/">list provided by jabber.at</a> of XMPP servers.</p>
<p>Notable mention for <a rel="nofollow" href="https://404.city/">404.city</a> itself. Not sponsored. Just a fan.</p>
<p>With regards to clients, the three mentioned above should get you started. Need a different client? Have a look at this <a rel="nofollow" href="https://xmpp.org/software/clients.html">list provided by xmpp.org</a>.</p>
<h2 id="End-to-end_encryption:_OMEMO">End-to-end encryption: OMEMO</h2>
<p>XMPP communication can be end-to-end encrypted with <a rel="nofollow" href="https://conversations.im/omemo/">OMEMO</a> (<a rel="nofollow" href="https://xmpp.org/extensions/xep-0384.html">XEP-0384</a>), the easiest and most common of <a rel="nofollow" href="https://wiki.404.city/en/XMPP_client_encryption">XMPP-compatible end-to-end encryption schemes</a>. Verifying OMEMO fingerprints is essential to trust your communication and keep it safe from Man-in-the-Middle attacks.</p>
<p>Each XMPP client you use will have its own OMEMO key, the content of which remains secured on your device but a "fingerprint" of which can be made public without a problem. These fingerprints are used to identify the different clients that have logged in on your XMPP account.</p>
<p>If you wish to secure your communication with OMEMO, make sure to choose a <a rel="nofollow" href="https://omemo.top/">client with full support on this website</a>.</p>
<h2 id="OMEMO_and_trust">OMEMO and trust</h2>
<p>When you talk with someone over XMPP and you want to guarantee all communication is secured, it is recommended to use a different form of communication to compare and trust each others fingerprints. Ideally, you would meet in person and scan QR codes, a handy function of the <strong>Conversations</strong> app.</p>
<h2 id="XMPP_identity_proofs_and_Keyoxide">XMPP identity proofs and Keyoxide</h2>
<p>As you can see, trusting OMEMO keys is an essential step in the process of ensuring communication is secure. Fortunately, <a rel="nofollow" href="https://keyoxide.org">Keyoxide</a> can assist you in that process.</p>
<p>As of <a rel="nofollow" href="https://codeberg.org/keyoxide/web/releases/tag/0.4.0">version 0.4</a>, Keyoxide generates QR codes for all <strong>verified</strong> XMPP accounts it detects. This makes it easy to add new contacts if your <a rel="nofollow" href="https://keyoxide.org/guides/xmpp">XMPP identity proof</a> looks like this:</p>
<pre style="background-color:#f9f9f9;color:#111111;"><code><span>proof@metacode.biz=xmpp:username@domain.org
</span></code></pre>
<p>Scan the resulting QR code on a Keyoxide profile page in the <strong>Conversations</strong> app and the contact is added. But the OMEMO keys are not yet trusted. Let's solve that!</p>
<h2 id="Integrating_OMEMO_in_the_XMPP_identity_proof">Integrating OMEMO in the XMPP identity proof</h2>
<p>It is also possible to add a more advanced <a rel="nofollow" href="https://keyoxide.org/guides/xmpp">XMPP identity proof</a> to your OpenPGP key that includes the OMEMO fingerprints:</p>
<pre style="background-color:#f9f9f9;color:#111111;"><code><span>proof@metacode.biz=xmpp:user@domain.org?omemo-sid-123456789=A1B2C3D4E5F6G7H8I9...
</span></code></pre>
<p>Obtaining the correct URI for the proof can be difficult when doing so manually. Fortunately, this can be assisted by the <strong>Conversations</strong> app. As you can tell, using the <strong>Conversations</strong> app brings a ton of advantages.</p>
<p>In the main menu of that app, press <strong>Manage accounts > [your account] > Share > Share as XMPP URI</strong> and add the resulting URI to your key using <a rel="nofollow" href="https://keyoxide.org/guides/xmpp">this Keyoxide guide</a>.</p>
<p>Scan the resulting QR code on a Keyoxide profile page and not only is the contact added, their OMEMO fingerprints are also fully trusted and verified.</p>
<h2 id="Why_trust_the_Keyoxide_identity_proof?">Why trust the Keyoxide identity proof?</h2>
<p>Anyone can add any XMPP proof to their OpenPGP key, whether they own it or not. So why trust the identity proof on Keyoxide?</p>
<p><strong>STEP 1</strong> The QR code is only shown if a XMPP identity proof is verified. Verifying a XMPP account requires the holder of said account to add a small line of code to their XMPP bio <a rel="nofollow" href="https://keyoxide.org/guides/xmpp">as described in this guide</a>. Only a person with access to both the OpenPGP private key and the XMPP account can verify that XMPP account.</p>
<p><strong>STEP 2</strong> While Keyoxide assists as much as possible with trusting the right proofs, a critical mind is always an asset when dealing with trusting online identities, especially when securing your communication. Do you recognize any other proofs on this person's profile page? Is this proof verified? If so, you can safely assume that the person who holds the OpenPGP key also has access to this "other proof".</p>
<p>Combining the two steps above, you can trust that you are talking to the right person and verifying the right OMEMO fingerprints.</p>
<h2 id="Example">Example</h2>
<p>You are reading this post on <a rel="nofollow" href="https://yarmo.eu">yarmo.eu</a>. Whether or not you trust me, I'm telling you that my OpenPGP fingerprint is:</p>
<pre style="background-color:#f9f9f9;color:#111111;"><code><span>9f0048ac0b23301e1f77e994909f6bd6f80f485d
</span></code></pre>
<p>So you visit <a rel="nofollow" href="https://keyoxide.org/9f0048ac0b23301e1f77e994909f6bd6f80f485d">keyoxide.org/9f0048ac0b23301e1f77e994909f6bd6f80f485d</a>. Indeed, whoever holds the key with that fingerprint also owns the <a rel="nofollow" href="https://yarmo.eu">yarmo.eu</a> domain.</p>
<p>Now, you scroll down until you reach the XMPP proof for <strong>yarmo@404.city</strong>. You read that the XMPP account is verified. Ergo, whoever holds the key with that fingerprint also has access to that XMPP account.</p>
<p>Final conclusion: whoever owns the <a rel="nofollow" href="https://yarmo.eu">yarmo.eu</a> domain also has access to the <strong>yarmo@404.city</strong> XMPP account. If you wish to talk with me securely, scan the QR code and be certain that you have just added me as a contact, and that are you verifying the right OMEMO fingerprints to ensure secure and fully encrypted communication between us.</p>
Launching Keyoxide.org2020-07-01T12:00:00+00:002020-07-01T12:00:00+00:00
Unknown
https://blog.keyoxide.org/keyoxide-launch/<p>Today, I'm excited to launch <a rel="nofollow" href="https://keyoxide.org">Keyoxide.org</a>, the lightweight and FOSS solution to make basic cryptography operations accessible to regular humans.</p>
<h2 id="What_is_Keyoxide.org?">What is Keyoxide.org?</h2>
<p><a rel="nofollow" href="https://keyoxide.org">Keyoxide.org</a> offers easy encryption, signature verification and decentralized identity proof verification based on PGP keys while demanding little in-depth knowledge about the underlying encryption program from its users.</p>
<p>This project aims to offer comparable functionality as services like <a rel="nofollow" href="https://keybase.io">Keybase</a> while reducing friction and being more open.</p>
<p>The project is MIT licensed, uses <a rel="nofollow" href="https://github.com/openpgpjs/openpgpjs">openpgpjs</a> and is hosted on <a rel="nofollow" href="https://codeberg.org/yarmo/keyoxide">Codeberg</a>.</p>
<h2 id="Why_only_encryption_and_signature_verification?">Why only encryption and signature verification?</h2>
<p>These are the operations that are available when only having access to public keys instead of private keys. If you wish to decrypt messages and sign them, you need a keypair. If you have a keypair, you probably have the knowledge to use dedicated tools like the CLI or Kleopatra. And if you do, you probably won't be using <a rel="nofollow" href="https://keyoxide.org">Keyoxide.org</a> directly yourself.</p>
<p>Indeed, if you possess a PGP keypair, <a rel="nofollow" href="https://keyoxide.org">Keyoxide.org</a> is the tool you send to others to interact with your public key more easily. Allow them to encrypt a message for you, to verify one of your signatures, to verify your online identities using decentralized proofs.</p>
<h2 id="What_are_those_decentralized_identity_proofs_you_keep_mentioning?">What are those decentralized identity proofs you keep mentioning?</h2>
<p>You know how Keybase allows you to prove you have control over accounts on certain websites and services? A great function! Fortunately for you, this function can be even better and more secure by using <a rel="nofollow" href="https://keyoxide.org/guides/openpgp-proofs">decentralized OpenPGP identity proofs</a>. <a rel="nofollow" href="https://keyoxide.org">Keyoxide.org</a> will prove your identity on multiple platforms at the same time and yet, you are not required to make an account to use this function. How is that possible?</p>
<p>Well, it's called <em>decentralized</em> for a reason: <a rel="nofollow" href="https://keyoxide.org">Keyoxide.org</a> doesn't hold your proofs, your key does! Any software that can access your public key can verify these proofs for anyone. When better tooling comes around, you could verify those proofs using a mobile app, using a command-line utility, you name it. No single service holds your proof, only you do, stored inside your keypair.</p>
<p>I have written a <a rel="nofollow" href="https://keyoxide.org/guides">guide</a> on how to add a proof for every platform currently supported by this website: <a rel="nofollow" href="https://keyoxide.org/guides/dns">domains</a>, <a rel="nofollow" href="https://keyoxide.org/guides/lobsters">Lobste.rs</a>, <a rel="nofollow" href="https://keyoxide.org/guides/twitter">Twitter</a>, <a rel="nofollow" href="https://keyoxide.org/guides/github">Github</a>, a <a rel="nofollow" href="https://keyoxide.org/guides">bunch more</a> and work is in progress to support even more still. Is your beloved service not in the list? <a rel="nofollow" href="https://codeberg.org/yarmo/keyoxide">Open an issue or make a PR</a>! Free open-source software FTW!</p>
<p>Oh, that reminds me, any <a rel="nofollow" href="https://keyoxide.org/guides/mastodon">Mastodon</a> instance can be used to prove your identity. Yes, <a rel="nofollow" href="https://github.com/keybase/keybase-issues/issues/3385">any</a>.</p>
<h2 id="So_how_does_it_compare_to_Keybase?">So how does it compare to Keybase?</h2>
<p>There's a more complete <a rel="nofollow" href="https://keyoxide.org/guides/feature-comparison-keybase">guide on the Keyoxide website</a>, but in a nutshell:</p>
<ul>
<li>more privacy-friendly by not forcing you to create an account and handing over data</li>
<li>more secure by not asking you to trust the service with your private keys</li>
<li>open-source servers (<a rel="nofollow" href="https://github.com/keybase/client/issues/24105">a must</a>)</li>
<li>encrypt/verify with every public key accessible on the internet, not just those that have been uploaded to a proprietary server</li>
<li>almost all processing is done in the browser, no data is sent to servers*</li>
<li>no vendor lock-in</li>
<li>selfhostable</li>
</ul>
<p>* Only exception is decentralized identity proof verification: some service providers do not have the correct CORS headers (like Reddit) or require APIs (like Twitter). In these rare cases, simple PHP scripts (also open-source) run the proof verification instead.</p>
<h2 id="Can_I_get_an_account?">Can I get an account?</h2>
<p>No. <a rel="nofollow" href="https://keyoxide.org">Keyoxide.org</a> doesn't need your data on its servers. There are already several ways of exposing public keys on the internet, including <a rel="nofollow" href="https://keyoxide.org/guides/web-key-directory">web key directory</a> (WKD) and dedicated servers like <a rel="nofollow" href="https://keys.openpgp.org">keys.openpgp.org</a>. Let's use those instead of making yet another service where you need to upload your keys to.</p>
<h2 id="Can_I_get_a_profile_page_then?">Can I get a profile page then?</h2>
<p>Yes! Append your PGP fingerprint or WKD id to the URL and there it is!</p>
<p>Want an example? Here's my profile at<br />
<a rel="nofollow" href="https://keyoxide.org/9f0048ac0b23301e1f77e994909f6bd6f80f485d">https://keyoxide.org/9f0048ac0b23301e1f77e994909f6bd6f80f485d</a>.</p>
<p>Now you know what accounts on various services are mine, where to follow me if you wish to get updates on the project and if you wish to send me an encrypted message, that's also just two clicks away.</p>
<h2 id="What_about_my_private_keys?">What about my private keys?</h2>
<p>Don't upload your private keys to the internet, period. If a service wants your private keys on their (proprietary) servers, say no.</p>
<h2 id="You_said_selfhostable?">You said selfhostable?</h2>
<p>Well, yes! It's not a fully supported use case just yet, but the browser does all the processing, the server is mostly just there to deliver the files to the user to perform the operations. <a rel="nofollow" href="https://codeberg.org/yarmo/keyoxide">Grab the code</a> and put it on your own PHP server!</p>
<h2 id="Any_closing_words?">Any closing words?</h2>
<p>I built this to provide better tooling around modern-day encryption programs and reduce the friction for less tech-savvy people when interacting with public keys.</p>
<p>For those who wish to use encryption programs beyond OpenPGP, <a rel="nofollow" href="https://codeberg.org/yarmo/keyoxide/issues">let's talk about this</a>. Keyoxide doesn't have any reference to PGP in its name for a reason: it could serve as a platform for easy interaction with any public key, no matter the underlying encryption program.</p>
<p>And above all, I hope you see the same benefit and potential in <a rel="nofollow" href="https://keyoxide.org">Keyoxide.org</a> as I do and would like to see it grow as an open and accessible platform to push forward the democratization of online privacy and security.</p>
<p>Privacy is not a luxury.</p>
<p>Many thanks to <a rel="nofollow" href="https://metacode.biz/@wiktor">Wiktor</a> for helping with the decentralized identity proofs.</p>