AIDs — Autonomous identifiers
Tags: ssi, web5, identity, decentralized
Published: 2023-07-18 07:51:48

If we take a look closer at the Trust Over IP spanning protocol. We will find that it focuses on AIDS—the site from the paper:

> **Autonomous identifiers (AIDs)** are **DIDs** generated algorithmically from a crypto- graphic key pair in such a way that they are self-certifying, i.e. the binding with the public key can be verified without the need to consult any external blockchain or third party. [KERI](https://keri.one/) is an example of a decentralized identity technology based entirely on AIDs. (c) [https://trustoverip.org/blog/2023/01/05/the-toip-trust-spanning-protocol/](https://trustoverip.org/blog/2023/01/05/the-toip-trust-spanning-protocol/)

We could subdivide all identifiers into more narrow categories.

-   **Non verifiable** — like UUIDs , URI , URNS, so they have some meaning only in context of internal systems.
-   **Verifiable** — Any system context identifier in a system that has a verification functionality. Example Id or access tokens of IdP providers, Domain names, DNS records, etc
-   **Crypto verifiable** — any identifier based on public/private key pair or symmetric key secret (rare example). So we shift integrity and verification to public cryptographically-based algorithms.
-   **Decentralized identifier** — a crypto-verifiable identifier that is independent of any centralized systems. See more in [https://www.w3.org/TR/did-core/](https://www.w3.org/TR/did-core/)
-   **Autonomous identifiers —** as mentioned, **self-certified** DID that do not depend on any third-party system or blockchain.

![](https://miro.medium.com/v2/resize:fit:1400/1*Vs1w3bejKCF0UAH20zr4-Q.png)

© [https://trustoverip.org/blog/2023/01/05/the-toip-trust-spanning-protocol/](https://trustoverip.org/blog/2023/01/05/the-toip-trust-spanning-protocol/)

To read more about trust spanning protocols read my article:

It is a cornerstone of AIDs. And AIDs is a basis of trust-spanning protocol that wants to be:

-   technology agnostic
-   self-contained
-   portable
-   interoperable

A self-certified identifier is generated, managed, and controlled by an individual or entity without the need for a centralized authority or third-party certification. In other words, the individual or entity asserts their identity without requiring an external party to verify it.

In decentralized identity systems, self-certified identifiers often provide more control and autonomy to individuals and organizations. They can be combined with cryptographic techniques, such as public and private key pairs, to ensure secure and private authentication, authorization, and communication.

Individuals and organizations can maintain control over their digital identities by using self-certified identifiers and minimizing reliance on third-party services. This approach can enhance privacy, security, and user autonomy in online interactions and transactions. However, it also requires a higher level of trust, as there is no external authority to validate the authenticity of the identifier.

Trust over IP refer to a KERI that is a more mature decentralized key management infrastructure. It is a topic for a different post, and we need to go much deeper into how KERI works.

For me, a Minimal Value Product and the most straightforward implementation of AIDs is a DID:KEY.

The idea is simple — self-certified, self-contained DID method that carries a public key as a part of the identifier in a multibase encoded value. Method supports a variety of cryptography suites.

![](https://miro.medium.com/v2/resize:fit:1400/1*auCtSirucwSEM3tCBIW46w.png)

**Lets implement one**

We could use DID key library that supports multiple cryptographic suites.

I selected **Secp256k1** as it is compatible with did:eth, did:polygon, did:elem and it will be a good illustration of how we could create different upgradable dids from the same key pairs.

All that we need is entropy or seed to generate a key pair and derive a did from it

```
import crypto from 'crypto';  
import \* as secp256k1 from '@transmute/did-key-secp256k1';  
const main = async ()=> {  
const { didDocument, keys } = await secp256k1.generate(  
  {  
    secureRandom: () => {  
      return crypto.randomBytes(32);  
    },  
  },  
  { accept: 'application/did+json' }  
);  
console.log( JSON.stringify({ didDocument }, null ,2))  
console.log( JSON.stringify({ keys }, null , 2))  
}  
main().then(r => console.log('run'))
```

We don't need to do anything with a didoc as far as it is calculated from did identifier on the fly.

```
{  
    "@context": \[  
      "https://www.w3.org/ns/did/v1",  
      "https://w3id.org/security/suites/jws-2020/v1"  
    \],  
    "id": "did:key:zQ3shvyWzXbjN1LEMohqeKcNYfy5yU2DuhGc5Fpy3xwoGZwid",  
    "verificationMethod": \[  
      {  
        "id": "did:key:zQ3shvyWzXbjN1LEMohqeKcNYfy5yU2DuhGc5Fpy3xwoGZwid#zQ3shvyWzXbjN1LEMohqeKcNYfy5yU2DuhGc5Fpy3xwoGZwid",  
        "type": "JsonWebKey2020",  
        "controller": "did:key:zQ3shvyWzXbjN1LEMohqeKcNYfy5yU2DuhGc5Fpy3xwoGZwid",  
        "publicKeyJwk": {  
          "kty": "EC",  
          "crv": "secp256k1",  
          "x": "8rQCxusQ9YGorgxWcE7AcmaAEyASbLdVL8UyhfBOq7Y",  
          "y": "i\_JDH5CZ-f2bmOQG1tsb5q31EUDR2eUE8wusI7rCtjs"  
        }  
      }  
    \],  
    "assertionMethod": \[  
      "did:key:zQ3shvyWzXbjN1LEMohqeKcNYfy5yU2DuhGc5Fpy3xwoGZwid#zQ3shvyWzXbjN1LEMohqeKcNYfy5yU2DuhGc5Fpy3xwoGZwid"  
    \],  
    "authentication": \[  
      "did:key:zQ3shvyWzXbjN1LEMohqeKcNYfy5yU2DuhGc5Fpy3xwoGZwid#zQ3shvyWzXbjN1LEMohqeKcNYfy5yU2DuhGc5Fpy3xwoGZwid"  
    \],  
    "capabilityInvocation": \[  
      "did:key:zQ3shvyWzXbjN1LEMohqeKcNYfy5yU2DuhGc5Fpy3xwoGZwid#zQ3shvyWzXbjN1LEMohqeKcNYfy5yU2DuhGc5Fpy3xwoGZwid"  
    \],  
    "capabilityDelegation": \[  
      "did:key:zQ3shvyWzXbjN1LEMohqeKcNYfy5yU2DuhGc5Fpy3xwoGZwid#zQ3shvyWzXbjN1LEMohqeKcNYfy5yU2DuhGc5Fpy3xwoGZwid"  
    \],  
    "keyAgreement": \[  
      "did:key:zQ3shvyWzXbjN1LEMohqeKcNYfy5yU2DuhGc5Fpy3xwoGZwid#zQ3shvyWzXbjN1LEMohqeKcNYfy5yU2DuhGc5Fpy3xwoGZwid"  
    \]  
  } 
```

As we can see, our did:key is: **did:key:zQ3shvyWzXbjN1LEMohqeKcNYfy5yU2DuhGc5Fpy3xwoGZwid**

Now we could go to [https://dev.uniresolver.io/](https://dev.uniresolver.io/) or use any resolver library to resolve a did document from it.

![](https://miro.medium.com/v2/resize:fit:1400/1*AxPf1uyo8aw5AjmAdrS6aQ.png)

So we are done and get our AID just in a few minutes.

But why does ToIP refer to KERI and not to a simple did: key?

The biggest downside and security issues :

-   We have a direct binding to a public key and identifier.
-   So as a result, we have no way to rotate the keys
-   We have no way to separate the controller from a public key

It is what KERI promises as a solution — complete separation of controller identifier and a key-pair.

![](https://miro.medium.com/v2/resize:fit:1400/1*_CqTQAz-0XBwvaPB-7TOcA.png)

© KERI paper [https://arxiv.org/pdf/1907.02143.pdf](https://arxiv.org/pdf/1907.02143.pdf)

It is critical for issuance and long-lived public identifiers. Still, it could be overkill or optional for ephemeral or short-lived private relations used in DIDComm connections, for example.

DIDComm community push a **did:peer** as an option for private communication identifiers and live door open for upgradable dids.

[https://identity.foundation/peer-did-method-spec/](https://identity.foundation/peer-did-method-spec/)

So **did:peer** level 0 mimic a did:key and even refer to did:key implementation. So for me, it is close brothers. More matured features came with a price of complexity and infrastructure.

We will talk about did peer and keri in next post.

You can take a look at my video

In next article we discover AIDs for Organisations