fedi-get-key v1.1.0
fedi-get-key
A library for fetching the public key from an activitypub actor, for use in fediverse applications. You can use this library to obtain a key for verifying an HTTP signature header, for example.
Note that you need to know the key ID URI in order to use this library - just knowing the actor's URI is not enough.
The document containing the key must use the sec:owner and
sec:publicKeyPem terms from the WC3 Security Draft vocabulary.
The document containing the key's owner must use the sec:publicKey term.
import KeyFetcher from 'fedi-get-key';
// Bring your own fetch implementation (the global fetch is fine)
const keyFetcher = new KeyFetcher(globalThis.fetch);
const keyUri = 'https://example.com/users/Paul#main-key';
const result = await keyFetcher.get(keyUri);
// This is the public key for the given URI
console.log(result.key); // "-----BEGIN PUBLIC KEY-----\n...etc...\n-----END PUBLIC KEY-----\n"
// This is the parsed JSON-LD document representing the key's owner
console.log(result.owner); // { @context: { etc }, id: 'https://example.com/users/Paul', preferredUsername: 'Paul', /* ...etc... */ }Ownership
As well as fetching the key, this library will check that there's a two-way relationship
between the key and its owner; the key must have a sec:owner property that
points to an actor, and that actor must have a sec:publicKey property
that points to the key.
These objects may be in the same document or in different documents - if the actor is in a separate document to the key, a second fetch request will be made to resolve the actor.
Fetch implementation
The KeyFetcher constructor accepts a fetch-like function as its argument. This function doesn't
need to implement the full fetch specification, just certain parts; namely, it must accept a
string url argument and options object of the form { headers: { accept: string } },
and return a response object with the ok and json properties and a headers collection
with a get function.
The typescript definitions are as follows:
type FetchLite = (url: string, options: FetchLiteOptions) => Promise<FetchLiteResponse>;
type FetchLiteOptions = {
headers: {
accept: string
}
}
type FetchLiteResponse = {
ok: boolean
status: number
headers: {
get(name: string): string | null
},
text(): Promise<string>
json(): Promise<unknown>
}While you can use the global fetch, you may wish to create a wrapper function which—for example—enforces HTTPS, aborts the request after a timeout, or caches responses.
Errors
If there is a problem with your request, the library will through a KeyError.
The error object has a meta object with the url, status and content of
the response.