Keyoxide Specification
Version 1
Keyoxide Specification
Author: Yarmo Mackenbach
Version: 1
Last updated: 2023-07-13
Abstract
The Keyoxide Specification provides a set of opinionated guidelines for designing interfaces and experiences related to the verification of decentralized online identities as described in the Ariadne Identity Specification.
Status
This version of the specification is frozen and superseded by v2.
Copyright notice
Copyright (c) 2022 Yarmo Mackenbach. All rights reserved.
1. Introduction
The principal function of a Keyoxide client app is to verify decentralized online identities. It does so through a combination of the following actions:
- fetch cryptographic keys;
- fetch cryptographically signed messages;
- extract identity claims and profile information from the cryptographic material;
- fetch data at locations deduced from the identity claims;
- compare cryptographic material and proofs to verify the identity claims.
If the Keyoxide client app can not run any or all of these tasks, it can request a Keyoxide server to do it in its place.
A Keyoxide instance does not store user profile data on its server. It dynamically fetches user profile data
2. Terminology
A Keyoxide profile is a collection of identity claims stored in a cryptographically secured document.
An identity claim is a link to an account hosted by a third party service provider, stored inside a cryptographically secured document. It requires an identity proof to be verified.
An identity proof is a link to a cryptographic keypair, hosted as part of an account on a third party serivce provider.
To view a Keyoxide profile is to fetch a cryptographically secured document, extract the identity claims it contains and verify them.
To verify an identity claim is to parse the claim, match it to potential service providers, deduce accessible locations that could contain an identity proof, fetch data from these locations and, if found, compare the identity proof to the cryptographically secured document that contained the claim.
3. HTTP Server
The API endpoints described in the following sections may be hosted on different domains.
3.1. Core API endpoints
/api/0/profile/fetch
- Description: fetch a Keyoxide profile
- URL parameters:
- query
- Desciption: the identifier for the cryptographic key (fingerprint, email address)
- Type: string
- doVerification
- Description: if true, the identity claims are verified
- Type: boolean
- protocol
- Description: specify the protocol to fetch the cryptographic key
- Type: string
- Values: ["hkp", "wkd"]
- query
- Returns: a JSON object as defined in 4.1.
/api/0/profile/verify
- Description: verify a Keyoxide profile obtained through /api/0/profile/fetch with doVerification=false
- URL parameters:
- data
- Desciption: the stringified JSON object obtained through /api/0/profile/fetch
- Type: string
- data
- Returns: JSON object as defined in 4.1.
3.1. Proxy API endpoints
/api/2/get/http
- Description: Proxy a HTTP request
- URL parameters:
- url
- Desciption: the address to request
- Type: string
- format
- Description: format of the
- Type: string
- Values: ["text", "json"]
- url
- Returns: string or JSON object
/api/2/get/dns
- Description: Proxy a DNS records request
- URL parameters:
- domain
- Desciption: the domain for which to get the TXT DNS records
- Type: string
- domain
- Returns: JSON object as defined in 4.2.
/api/2/get/xmpp
- Description: Proxy a XMPP vCard request
- URL parameters:
- id
- Desciption: the jabber id to query
- Type: string
- field
- Desciption: the vCard field to query
- Type: string
- id
- Returns: JSON object
/api/2/get/twitter
- Description: Proxy a Twitter API request
- URL parameters:
- tweetId
- Desciption: the id of a tweet
- Type: int
- tweetId
- Returns: JSON object
/api/2/get/matrix
- Description: Proxy a Matrix API request
- URL parameters:
- roomId
- Desciption: the id of a Matrix room
- Type: string
- eventId
- Desciption: the id of an event in the Matrix room
- Type: string
- roomId
- Returns: JSON object
/api/2/get/telegram
- Description: Proxy a Telegram API request
- URL parameters:
- user
- Desciption: the username of a Telegram account
- Type: string
- chat
- Desciption: the name of a Telegram group chat
- Type: string
- user
- Returns: JSON object
/api/2/get/irc
- Description: Proxy an IRC taxonomy request
- URL parameters:
- nick
- Desciption: the nickname of a IRC account
- Type: string
- domain
- Desciption: the domain of the server that hosts the IRC account
- Type: string
- nick
- Returns: JSON object
/api/2/get/gitlab
- Description: Proxy a Gitlab request
- URL parameters:
- username
- Desciption: the username of a Gitlab account
- Type: string
- domain
- Desciption: the domain of the server that hosts the Gitlab account
- Type: string
- username
- Returns: JSON object
/api/2/get/activitypub
- Description: Proxy an ActivityPub request
- URL parameters:
- url
- Desciption: the URL of an ActivityPub profile
- Type: string
- url
- Returns: JSON object
4. Data schemas
4.1. JSON schema for a Keyoxide profile
{
"$schema": "http://json-schema.org/draft-07/schema",
"$id": "https://keyoxide.org/profile.schema.json",
"type": "object",
"properties": {
"keyData": {
"type": "object",
"properties": {
"fingerprint": {
"type": "string"
},
"openpgp4fpr": {
"type": "string"
},
"users": {
"type": "array",
"items": {
"type": "object",
"properties": {
"userData": {
"type": "object",
"properties": {
"id": {
"type": "string"
},
"name": {
"type": "string"
},
"email": {
"type": "string"
},
"comment": {
"type": "string"
},
"isPrimary": {
"type": "boolean"
},
"isRevoked": {
"type": "boolean"
}
}
},
"claims": {
"type": "array",
"items": {
"type": "object",
"properties": {
"claimVersion": {
"type": "integer"
},
"uri": {
"type": "string"
},
"fingerprint": {
"type": "string"
},
"status": {
"type": "string"
},
"matches": {
"type": "array",
"items": {
"type": "object",
"properties": {
"serviceProvider": {
"type": "object",
"properties": {
"type": {
"type": "string"
},
"name": {
"type": "string"
}
}
},
"match": {
"type": "object",
"properties": {
"regularExpression": {
"type": "object"
},
"isAmbiguous": {
"type": "boolean"
}
}
},
"profile": {
"type": "object",
"properties": {
"display": {
"type": "string"
},
"uri": {
"type": "string"
},
"qr": {
"type": "string"
}
}
},
"proof": {
"type": "object",
"properties": {
"uri": {
"type": "string"
},
"request": {
"type": "object",
"properties": {
"fetcher": {
"type": "string"
},
"access": {
"type": "string"
},
"format": {
"type": "string"
},
"data": {
"type": "object"
}
}
}
}
},
"claim": {
"type": "array",
"items": {
"type": "object",
"properties": {
"format": {
"type": "string"
},
"relation": {
"type": "string"
},
"path": {
"type": "array",
"items": {
"type": "string"
}
}
}
}
}
}
}
},
"verification": {
"type": "object"
},
"summary": {
"type": "object",
"properties": {
"profileName": {
"type": "string"
},
"profileURL": {
"type": "string"
},
"serviceProviderName": {
"type": "string"
},
"isVerificationDone": {
"type": "boolean"
},
"isVerified": {
"type": "boolean"
}
}
}
}
}
}
}
}
},
"primaryUserIndex": {
"type": "integer"
},
"key": {
"type": "object",
"properties": {
"data": {
"type": "object"
},
"fetchMethod": {
"type": "string"
},
"uri": {
"type": "string"
}
}
}
}
},
"keyoxide": {
"type": "object",
"properties": {
"url": {
"type": "string"
}
}
},
"extra": {
"type": "object",
"properties": {
"avatarURL": {
"type": "string"
}
}
},
"errors": {
"type": "array"
}
},
"required": [
"keyData",
"keyoxide",
"extra",
"errors"
],
"additionalProperties": false
}
4.2. JSON schema for proxied DNS records
{
"$schema": "http://json-schema.org/draft-07/schema",
"$id": "https://keyoxide.org/dns.proxy.schema.json",
"type": "object",
"properties": {
"domain": {
"type": "string"
},
"records": {
"type": "object",
"properties": {
"txt": {
"type": "array",
"items": {
"type": "string"
}
}
}
}
},
"required": [
"domain",
"records"
],
"additionalProperties": false
}