Identity System & User Profiles

Cloudillo Profiles are located using a DNS-based identity system. Each Cloudillo Identity is associated with a specific API endpoint, which can be accessed via the “cl-o” subdomain of the identity. For example, the API domain of the cloudillo.net identity is available at https://cl-o.cloudillo.net/.

Retrieving a Cloudillo Profile

Fetch a profile by requesting the /api/me endpoint of the identity’s API domain. It is unauthenticated, so any peer (or client) can read it:

curl https://cl-o.cloudillo.net/api/me

The response is wrapped in the standard API envelope (data, time):

{
  "data": {
    "idTag": "cloudillo.net",
    "name": "Cloudillo",
    "type": "community",
    "profilePic": "QoEYeG8TJZ2HTGhVlrtTDBpvBGOp6gfGhq4QmD6Z46w",
    "keys": [
      {
        "keyId": "250205",
        "publicKey": "MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAE..."
      }
    ]
  },
  "time": "2025-02-05T12:00:00Z"
}

Profile Fields

  • idTag: The identity tag (DNS-based identifier) of the profile.
  • name: The display name.
  • type: "person" for personal profiles or "community" for communities.
  • profilePic: File ID of the profile picture, retrievable via the storage API.
  • keys: The profile’s public signing keys (see below).

For the owner-facing view with cover image and extended metadata, clients use /api/me/full.

Profile Picture Retrieval

The profilePic field is a file ID that resolves through the Cloudillo Storage API:

curl https://cl-o.nikita.cloudillo.net/api/store/NMzE4gNI29aEkiV6Q7I1UNWh4x2gFZ7753Pl74veYtU

Key Management

A profile can hold multiple signing keys, enabling periodic key rotation while older keys remain valid for verifying past actions.

Key Structure

Each entry in the keys array is published with three fields:

pub struct AuthKey {
    key_id: Box<str>,              // "keyId": date-based ID, e.g. "250205"
    public_key: Box<str>,          // "publicKey": P-384 public key (PKCS#8 PEM)
    expires_at: Option<Timestamp>, // "expiresAt": optional expiration
}

Private keys are held only in the AuthAdapter and never appear in the response.

Cryptographic Algorithm

Signing keys use the P-384 elliptic curve (NIST P-384 / secp384r1). Action tokens are signed with ES384 (ECDSA over P-384 with SHA-384).

Key Rotation

The key ID is the creation date in YYMMDD format (e.g. 250205). To rotate, the server generates a new key, adds it alongside the existing ones, and marks the old key as expired. Because each action token records the keyId it was signed with, old tokens stay verifiable against the matching (expired) key.

Push Notification Keys

Web push uses a separate per-tenant VAPID key pair (ES256 / P-256), stored in the AuthAdapter. These are independent from the signing keys above and are not part of the /api/me response. See Network & Security for the full cryptography table.

Identity Resolution

DNS-Based Discovery

Cloudillo uses DNS to discover the API endpoint for an identity:

  1. Identity: alice.example.com
  2. API Domain: cl-o.alice.example.com
  3. API Endpoint: https://cl-o.alice.example.com/api/me

Cloudillo Identity Providers (CIP)

Users without their own domain can use a Cloudillo Identity Provider:

CIP Responsibilities:

  • Domain management (subdomains or custom domains)
  • DNS configuration
  • Dynamic DNS support
  • CIPs never store or access any user data, nor have any responsibility for it.

Example CIP: cloudillo.net

  • Provides identities like alice.cloudillo.net
  • API available at https://cl-o.alice.cloudillo.net
  • Users can migrate to their own domain later

Custom Domain Setup

To use your own domain with Cloudillo:

  1. DNS Configuration:
cl-o.alice.example.com.  A      <your-server-ip>
cl-o.alice.example.com.  AAAA   <your-server-ipv6>
app.example.com.  A             <your-server-ip>
app.example.com.  AAAA          <your-server-ipv6>
  1. TLS Certificate: Automatic via ACME (Let’s Encrypt)
ACME_EMAIL=admin@example.com
  1. Bootstrap: Configure tenant
BASE_ID_TAG=alice.example.com
BASE_APP_DOMAIN=app.example.com
BASE_PASSWORD=<secure-password>

Profile Metadata & Synchronization

Display metadata (name, type, profile picture, extended sections) lives in the MetaAdapter; the ProfileType enum is either Person or Community. Signing keys live in the AuthAdapter. The /api/me handler combines both.

When an instance interacts with a remote identity, it fetches https://cl-o.{remote_id_tag}/api/me and caches the result locally. The response carries an ETag, so frequent re-syncs answer 304 Not Modified when nothing has changed.

Security Considerations

Public Key Infrastructure

  • Public keys are publicly accessible via /api/me
  • Private keys are stored securely in AuthAdapter
  • No private key export - keys never leave the server
  • Key verification happens on every action token

Identity Trust Model

Trust is established through:

  1. DNS ownership: Control of domain proves identity ownership
  2. Key signatures: Private key proves control of identity
  3. HTTPS: TLS proves server authenticity
  4. Action signatures: ES384 signatures prove action authenticity

Attack Mitigation

DNS Hijacking:

  • Old signatures remain valid (past actions can’t be forged)
  • Users can verify key changes

Key Compromise:

  • Rotate immediately to a new key and mark the compromised key as expired
  • Legitimate past actions remain verifiable (each token pins its keyId)

Server Compromise:

  • Private keys in AuthAdapter may need HSM/vault for high-security deployments
  • Separate AuthAdapter storage from other adapters
  • Regular security audits

API Reference

GET /api/me

Retrieve public profile information, including the signing keys used to verify this identity’s action tokens. Unauthenticated.

Request:

curl https://cl-o.example.com/api/me

Response (200 OK, wrapped in the standard data envelope):

{
  "data": {
    "idTag": "example.com",
    "name": "Alice",
    "type": "person",
    "profilePic": "f1~Qo...46w",
    "keys": [
      { "keyId": "250205", "publicKey": "MHYwEAYHKoZIzj0CAQ..." }
    ]
  }
}

GET /api/me/full returns the same fields plus the cover image and the tier-filtered extended metadata (x) map for the owner-facing UI.

See Also