Files
alknet/docs/research/references/distributed-identity/distributed-identity-reference.md
glm-5.1 f620a94705 Add Phase 2 definitions, terminology disambiguation, and reference research docs
- definitions.md: formal term disambiguation for overloaded concepts
  (service, interface, token, identity, domain) with cross-domain mapping
  tables (alknet ↔ Keystone, distributed git, rustfs) and 8 open questions
- references/rustfs/: research on rustfs S3 store, Keystone/OIDC integration,
  and credential mapping to CredentialSet
- references/gitserver/: research on gitserver library architecture and
  integration paths as HTTP MessageInterface and SSH adapter
- references/openstack-keystone/: research on Keystone identity concepts
  (tokens, scoping, service catalog, RBAC, trust delegation, federation)
  and what alknet should adopt vs skip
- references/distributed-identity/: research on decentralized git, smart
  contract ACL, on-chain identity, and Radicle comparison
2026-06-08 14:59:56 +00:00

41 KiB

Research: Distributed Identity, Smart Contract ACL, and Decentralized Git

Status: Research Reference Created: 2026-06-08 Scope: Decentralized git hosting, distributed identity, smart contract-based access control, and their relevance to alknet

Table of Contents

  1. Executive Summary
  2. Source Concept: NFT-Based Decentralized Git
  3. Existing Projects
  4. Identity on the Blockchain
  5. Access Control Models for Distributed Git
  6. Cryptographic Identity Mapping
  7. Gossip Protocols for Repo Synchronization
  8. Relevance to Alknet
  9. References

1. Executive Summary

This document researches distributed identity systems, smart contract-based access control, and decentralized git platforms to inform alknet's architecture. The source concept — a decentralized, censorship-resistant git hosting platform using NFTs (ERC-721) for identity and smart contracts for ACL — directly inspired some of alknet's cryptographic identity and key derivation ideas. The research reveals several key findings:

Key Findings:

  1. Radicle is the most mature decentralized git system and provides the closest production reference for alknet's architecture, particularly in Ed25519 identity, gossip-based replication, and self-certifying repositories. However, Radicle lacks the smart contract/on-chain ACL layer that the source concept envisions.

  2. Smart contract ACL is feasible but introduces latency trade-offs. On-chain identity verification costs 0.5-5 seconds per look-up on L2s, making it unsuitable as a hot path. The correct pattern is on-chain registration + local cache, which aligns with alknet's StorageIdentityProvider approach.

  3. alknet's BIP39/SLIP-0010 key derivation already spans both worlds. The m/74'/0'/0'/0' path for Ed25519 identity and m/44'/60'/0'/0/0 for Ethereum signing means the same seed phrase that governs alknet authentication can also sign on-chain transactions — no separate wallet needed.

  4. The Identity + IdentityProvider model maps directly to decentralized identity. ConfigIdentityProvider is the local-only mode (Radicle-like); StorageIdentityProvider is the cached mode (on-chain ACL mirrored to SQLite); a future OnChainIdentityProvider could verify against smart contracts.

  5. Domain events vs. integration events (from alknet's event sourcing research) is the correct pattern for synchronizing on-chain state to local nodes. On-chain events are the source of truth; honker streams carry the projected local state.


2. Source Concept: NFT-Based Decentralized Git

The originating concept for this research is a decentralized, censorship-resistant git hosting platform built on the following principles:

2.1 Core Architecture

Component Mechanism Purpose
Org/User Identity Transferable ERC-721 tokens Organizations and users are NFTs; ownership is on-chain and transferable
Repository Identity ERC-721 tokens owned by org/user tokens Repos are NFTs with a mapping(address => Role) ACL
Replicators User/org nodes listing replicated repos + public endpoints Decentralized hosting; replicators choose what to mirror
Gossip Protocol Push/pull notifications about repo updates Replicators learn about new commits from tracked repos
Push Authorization Identity's on-chain ACL verified by replicator No central authority can ban; replicators individually verify write privileges
Funding Model After-the-fact Patreon-like contributions Replicators receive donations; no paywall for access

2.2 Key Design Properties

  • No central authority: No single entity can ban an org, user, or repo
  • Individual replicator choice: Each replicator independently decides what to replicate and whose pushes to accept
  • Transferable identity: Selling the org NFT transfers all repos and access permissions
  • Self-certifying data: Git content addresses + on-chain identity = verifiable data provenance

2.3 Critical Gaps in the Source Concept

Gap Issue Solution Pattern
Hot path latency On-chain ACL look-up per push is too slow Cache ACL locally; sync from chain events
Key rotation If the private key controlling the NFT is lost, the identity is lost Multi-delegate thresholds (like Radicle) + social recovery
Fork/namespace collisions Multiple repos with same name under different orgs Use on-chain IDs (token IDs) not human-readable names as the authoritative identifier
Gas costs Every ACL change costs gas Batch updates; use L2s (Base, Arbitrum); delegate to replicator-level local ACL
Revocation propagation Revoking write access must propagate to all replicators Event-driven: on-chain Revoked event → gossip notification → local ACL update

3. Existing Projects

3.1 Radicle (radicle.xyz)

Overview: Radicle is an open-source, peer-to-peer code collaboration stack built on Git. It is the most mature decentralized git system currently in production (v1.x, Heartwood release).

Identity System

Feature Implementation
Node ID (NID) Ed25519 public key encoded as a DID (did:key:z6Mk...)
Key format Ed25519 (same curve as alknet)
Storage SSH-format key files; MemorySigner holds decrypted key in RAM
Multi-device Currently one key per device (per RIP-0002); multi-device via threshold delegates is in development
Identity Document JSON document stored in Git, listing delegates (DIDs) and a threshold for canonical updates

Relevance to alknet: Radicle's NID system is architecturally very close to alknet's Ed25519-based identity. Both use:

  • Ed25519 as the primary key type
  • A single seed/identity as the root of trust
  • DID-like identifiers for inter-node communication
  • Cryptographic signatures for data verification

Key difference: Radicle uses pure Ed25519 keypairs directly (no hierarchical derivation), while alknet derives Ed25519 keys from a BIP39 seed phrase via SLIP-0010. This gives alknet the ability to derive multiple keys from a single root and to derive Ethereum signing keys from the same seed.

Gossip Protocol

Radicle uses a custom gossip protocol with three message types:

Message Type Purpose Content
Node Announcement Peer discovery Node ID, alias, addresses, capabilities, timestamp
Inventory Announcement Repo discovery List of RepoIDs being seeded, timestamp
Reference Announcement Repo update notification RepoID + updated signed refs, timestamp

Each announcement includes a cryptographic signature and timestamp, enabling verification before relay. Messages are dropped on re-encounter (epidemic-style deduplication). Bootstrap nodes seed peer discovery.

Comparison with alknet's call protocol: Radicle's gossip is metadata-only; actual data transfer uses Git protocol. alknet's approach uses a call protocol (EventEnvelope) for both metadata and operation invocation. The gossip pattern could be layered on top of alknet's call protocol as a subscription-based integration event mechanism.

Self-Certifying Repositories

Radicle repositories are self-certifying:

  • The Repository ID (RID) is derived from the initial identity document hash
  • All actions (commits, issue comments, patches) are cryptographically signed
  • Delegates are public keys authorized to update the identity document
  • A threshold defines how many delegates must sign for an update to be canonical
  • Canonical branches are established dynamically based on signature thresholds

This eliminates the need for a central authority to determine "which version is correct."

Relevance: alknet's on-chain ACL concept (from the source) can use this threshold model. Instead of a single NFT owner dictating the canonical branch, a threshold of delegates can be required — this mirrors the narrowed_scopes / DelegatesEdge model in alknet's ACL graph.

Collaborative Objects (COBs)

COBs are Radicle's mechanism for distributed social artifacts (issues, patches, code review):

  • Stored as Git objects in refs/cobs/<type>/<object-id> namespace
  • Use CRDT DAG (Directed Acyclic Graph) for conflict-free merging
  • All operations are Ed25519-signed by their author
  • SQLite cache (cobs.db) provides indexed queries without traversing Git history

Relevance: COBs demonstrate that complex social data can be stored in Git with CRDT semantics. alknet's alknet-storage metagraph + honker streams could serve a similar role for distributed state, with the key difference being that alknet's state store is SQLite-backed rather than Git-backed, making it more efficient for real-time operations.

Summary Assessment

Dimension Radicle alknet (proposed)
Identity Ed25519 keypair (DID) Ed25519 from SLIP-0010 + Ethereum key from same seed
Naming No global naming; NID is identifier On-chain NFT ID + human-readable name (via ENS or custom)
Access Control Threshold delegates in identity doc Smart contract ACL + local graph cache
Replication Gossip for metadata, Git for data Call protocol + (future) gossip subscriptions
Data Storage Git objects + SQLite cache SQLite (metagraph/honker) + Git-compatible
Censorship Resistance P2P, no authority P2P + on-chain identity (uncensorable registration)
Funding Model Community-funded seed nodes After-the-fact contributions (replicators)

3.2 ForgeFed (Forgejo Federation)

Overview: ForgeFed is an ActivityPub-based federation protocol for software forges. It enables Gitea/Forgejo instances to interoperate — users on one instance can open issues and submit PRs on another without creating separate accounts.

Feature Details
Protocol ActivityPub (same as Mastodon, PeerTube)
Identity Web-based (user@example.com format, like email)
ACL Per-instance ACL; no on-chain verification
Censorship Resistance Limited; instances can block each other
Status Forgejo implementing; Vervis is reference implementation

Relevance to alknet: ForgeFed shows how federation works without blockchain. It uses ActivityPub for cross-instance communication, which is analogous to alknet's call protocol for cross-node communication. However, ForgeFed relies on instance-level trust (each Forgejo admin controls their instance), while alknet's concept uses on-chain identity for trust.

Key takeaway: ForgeFed's federation model is complementary, not competitive, with blockchain identity. An alknet node could expose a ForgeFed-compatible interface for interop with existing forges while using on-chain identity for internal trust decisions.

3.3 Git-Based Smart Contract Projects

Project Chain Approach Status
GitBross Solana/Arbitrum + IPFS Repos backed up to IPFS; smart contracts for metadata Active
GitLike Ethereum + IPFS Browser-based decentralized VCS Experimental
Statik IPFS Version control on IPFS with content-addressed storage Experimental
PineSU Ethereum Git repos + blockchain for integrity/timestamping Research paper

Common patterns:

  • IPFS for content-addressed storage of git objects
  • Smart contracts for metadata (ownership, ACL, provenance)
  • Ethereum or L2 for on-chain verification
  • Git bridge tools that push to both IPFS and traditional remotes

Key insight: None of these projects have achieved widespread adoption. The main challenges are:

  1. Performance: IPFS retrieval is slower than centralized git hosting
  2. UX: Browser-based git clients lack feature parity with CLI tools
  3. Incentives: No sustainable funding model for replicators

alknet's approach of using traditional git remotes with a smart contract ACL overlay avoids the IPFS performance trap while still providing censorship resistance.

3.4 NFT-Based Access Control Systems

Several projects use NFTs (ERC-721) for access gating:

Pattern Mechanism Example
Token-gated content Wallet verification proves NFT ownership before granting access NFT-gated websites, Discord roles
Role-based ACL via NFT NFTs represent roles; smart contract checks balanceOf(address) > 0 Token-gated DAOs, access-controlled channels
Namespace NFTs Each NFT represents a namespace/org; sub-rights derive from ownership ENS domains, NFT-based guild systems

Solidity Pattern for Repository ACL:

// Simplified example: NFT-based org/repo with on-chain ACL
contract OrgToken is ERC721 {
    struct Org {
        address owner;
        mapping(address => Role) members; // ACL mapping
    }
    
    struct Repo {
        uint256 orgTokenId;     // Owning org
        mapping(address => Permission) collaborators;
    }
    
    function canPush(uint256 repoId, address user) external view returns (bool) {
        Repo storage repo = repos[repoId];
        // Check direct permission
        if (repo.collaborators[user] >= Permission.Write) return true;
        // Check org membership
        Org storage org = orgs[repo.orgTokenId];
        if (org.members[user] >= Role.Member) return true;
        return false;
    }
}

Performance considerations: A canPush() check on L2 (Base, Arbitrum) costs ~0.001-0.01 USD and takes 0.5-2 seconds. This is acceptable for occasional operations (repo creation, ACL changes) but not for per-push verification. Caching is essential.

Relevance to alknet: The mapping from on-chain ACL to alknet's local ACL graph is direct:

  • ERC-721 token ID → PrincipalNode in alknet's ACL metagraph
  • collaborators mapping → DelegatesEdge with narrowed_scopes
  • canPush() → alknet's check_access() function

4. Identity on the Blockchain

4.1 ERC-721 as Identity/Namespace Tokens

How it works: Each unique identity (org, user, namespace) is an ERC-721 NFT. The token ID is the on-chain identifier; metadata (display name, avatar, public key) is stored off-chain (IPFS or DNS).

Advantages:

  • Inherent transferability (sell/gift an org identity)
  • On-chain ownership verification
  • Metadata can include cryptographic public keys for off-chain verification
  • Composable with other on-chain protocols (DAO governance, treasury)

Disadvantages:

  • Gas costs for every state change
  • Key rotation requires a transaction (can't just change a local file)
  • Metadata availability depends on off-chain storage
  • Privacy: all ACL changes are public on-chain

Resolution pattern: Use on-chain registration as the root of trust, but resolve identity locally via cached data. This is exactly how DNS works — the zone file is authoritative, but resolvers cache it.

4.2 ENS (Ethereum Name Service) as a Naming Layer

Overview: ENS maps human-readable names (e.g., alice.eth) to machine-readable identifiers (Ethereum addresses, content hashes, text records).

Feature Implementation
Name resolution alice.eth → Ethereum address (NFT owner)
Text records Store arbitrary key-value data (avatar, email, public key, SSH key)
Subdomains git.alice.eth can point to a replicator endpoint
Resolver Smart contract that returns records for a name
Off-chain look-up CCIP-read (EIP-3668) allows resolving names via external data

Relevance to alknet: ENS text records can store alknet node identifiers:

  • alk.id text record → alknet Node ID (Ed25519 public key fingerprint)
  • alk.pubkey text record → Ed25519 public key (for SSH authentication)
  • alk.replicator text record → endpoint URL (for repo discovery)

This creates a human-friendly naming overlay on top of alknet's cryptographic identifiers. Combined with DNS TXT records (alknet's planned DNS naming layer), it provides multiple resolution paths.

Limitation: ENS resolution requires an Ethereum RPC call, which adds latency. For production use, ENS data should be cached locally and refreshed periodically, similar to DNS TTLs.

4.3 Smart Contracts as ACL/Naming Services

Pattern: A smart contract stores the ACL mapping and provides a view function for verification. This is the "source of truth" that local caches sync from.

On-chain ACL contract (source of truth)
         │
         │ events: RoleGranted, RoleRevoked, RepoCreated, etc.
         │
         ▼
alknet-storage (local cache)
  ├── ACL metagraph (PrincipalNode + DelegatesEdge)
  ├── Synced from on-chain events
  └── Used for hot-path access checks

Event-driven sync pattern (critical for alknet):

  1. Smart contract emits RoleGranted(address, repoId, role) event
  2. alknet head node listens to these events (via Ethereum log subscription)
  3. Event is projected into the ACL metagraph as a DelegatesEdge with narrowed_scopes
  4. Local access checks use the metagraph (fast, SQLite)
  5. Periodic consistency check ensures local cache matches on-chain state

This maps directly to alknet's event boundary discipline:

  • On-chain events = external source of truth (like domain events from another service)
  • ACL metagraph = local projection (like an integration event or read model)
  • Honker stream acl:updated = notification that the local cache changed (integration event)

4.4 Decentralized Identity Standards

W3C DIDs (Decentralized Identifiers)

Overview: DIDs are a W3C standard for verifiable, self-sovereign digital identifiers. A DID is a URI that resolves to a DID Document describing how to interact with the identity holder.

DID Method Resolution Key Type Use Case
did:key Static (no registry) Ed25519, secp256k1, etc. Radicle uses this; self-certifying
did:ethr Ethereum registry secp256k1 Blockchain-verifiable identity
did:web DNS/web server Any Traditional web PKI bridge
did:ion Bitcoin Sidetree secp256k1 Microsoft's DID system

Relevance: Radicle uses did:key with Ed25519 keys. alknet could use did:key for local identity (same key type!) and extend to did:ethr for on-chain identity, using the same seed phrase to derive both keys.

Verifiable Credentials (VCs)

Overview: VCs are tamper-evident, cryptographically secure attestations issued by a trusted authority. Think of them as digital certificates (driver's license, degree) that the holder presents to a verifier.

Application to git access: A VC could attest that "this Ed25519 public key has write access to repo X." The issuer is the org's NFT contract (or a delegate). VCs can be verified off-chain, reducing on-chain transaction costs.

alknet mapping: VCs are analogous to alknet's Identity struct with scopes and resources. A VC issuance maps to the creation of a DelegatesEdge in the ACL graph. The key difference is that VCs are bearer tokens (anyone who holds one can present it), while alknet's ACL is graph-based (the principal must be connected to the resource via edges).


5. Access Control Models for Distributed Git

5.1 Git's Own ACL Model

Git has limited built-in ACL. Access control is typically enforced at the transport layer:

Mechanism Layer Scope
pre-receive hook Server-side Reject pushes based on branch, author, file patterns
update hook Server-side Per-ref checks (branch-level protection)
post-receive hook Server-side Post-push actions (notifications, CI triggers)
SSH key mapping Transport authorized_keys → system user → filesystem permissions
HTTP basic auth Transport Username/password → Git smart HTTP
Gitolite Server-side Config-file-based ACL mapping SSH keys to repos and permissions

Gitolite pattern (most relevant for distributed git):

  • ~/.ssh/authorized_keys maps SSH keys to Gitolite users
  • ~/.gitolite/conf/gitolite.conf defines repos and permissions
  • Permission levels: R (read), RW (read+write), RW+ (read+write+force-push)
  • Wildcard repos: CREATOR/..* — users can create repos matching patterns

alknet mapping: Gitolite's config file is the analog of alknet's ACL metagraph. The key difference is that Gitolite is centralized (one config file), while alknet's ACL can be distributed (synced from on-chain events).

5.2 Decentralized Write Permission Without Central Authority

In a truly decentralized system, no single node controls access. Several patterns exist:

Pattern 1: Self-Certifying Repositories (Radicle)

  • The repo creator defines an identity document listing delegates
  • Delegates are Ed25519 public keys with a threshold
  • Only delegate signatures on refs are considered canonical
  • Replicators accept any push but only replicate refs signed by sufficient delegates

Trade-off: Simple, no on-chain costs, but no mechanism for human-readable names or transferable ownership.

Pattern 2: On-Chain ACL (Source Concept)

  • Smart contract stores mapping(address => Role) for each repo
  • Replicators verify pusher's address against the contract before accepting
  • Ownership is transferable (the NFT can be sold)
  • Gas costs for setup and ACL changes

Trade-off: Transferable ownership and verifiable ACL, but requires Ethereum interaction and introduces latency.

Pattern 3: Hybrid — On-Chain Root + Local Cache

  • On-chain contract defines who owns each org/repo NFT
  • Local ACL graph caches on-chain state and adds local rules
  • Hot-path checks use local cache (SQLite, fast)
  • Cold-path operations (ACL changes, ownership transfers) go on-chain
  • Local cache is periodically verified against on-chain state

This is the recommended pattern for alknet. It combines:

  • On-chain censorship resistance (no single authority can revoke identity)
  • Local performance (ACL checks are SQLite-fast)
  • Transferable ownership (NFT can be sold/transferred on-chain)
  • Graceful degradation (local ACL still works when chain is unavailable)

5.3 Radicle's Approach to Identity and Verification

Radicle's identity model has specific properties worth detailed comparison:

Property Radicle alknet (proposed)
Identity root Ed25519 keypair (generated locally) BIP39 seed phrase → SLIP-0010 derivation
Identity document JSON in Git, signed by delegates On-chain NFT + local ACL metagraph
Delegate model Threshold of N public keys Threshold of N delegates (on-chain or local)
Key rotation Add/remove delegates via identity doc update Transfer NFT to new address; update local keys
Multi-device One key per device (RIP-0002) One key per device derived from same seed (m/74'/0'/0'/{n}')
Namespace collision RID is content-hash, collision-free NFT token ID is unique; human names via ENS
Revocation Remove delegate from identity doc On-chain ACL change + local cache update
Verification Signature verification against delegate list Signature verification + on-chain ACL check

alknet advantage: Deriving multiple keys from one seed means:

  • Multi-device support is built-in (derive a key per device)
  • No "one key per identity" limitation
  • The same seed provides identity keys, encryption keys, SSH keys, and Ethereum signing keys
  • Key rotation for a single device is: derive a new key from the next index, updated locally

alknet challenge: If the seed phrase is lost, all derived keys are lost. Mitigation strategies:

  • Social recovery (N-of-M threshold: trusted contacts hold shards)
  • Hardware security module (HSM) protection for the seed
  • Multi-sig on key operations (require threshold of devices to authorize)

6. Cryptographic Identity Mapping

6.1 Ed25519 Keys (alknet's Key Type)

alknet uses Ed25519 as the primary key type for:

  • SSH authentication (fingerprint-based verification)
  • Node identity (Node IDs are Ed25519 public keys)
  • Channel signing (call protocol event signatures)

Relevant properties of Ed25519:

  • 32-byte public key, 64-byte private key (or 32-byte seed + 32-byte public key)
  • Deterministic signatures (same message, same key → same signature)
  • Fast verification (~3x faster than secp256k1)
  • Used in SSH (since OpenSSH 6.5), Tor onion services, Signal

SLIP-0010 derivation (what alknet uses):

  • SLIP-0010 generalizes BIP-32 to non-secp256k1 curves
  • Ed25519 derivation uses hardened keys only (cannot derive child public keys from parent public key)
  • This means: the master seed must be available to derive any child key
  • alknet's secret service holds the seed in RAM and derives keys on demand

6.2 Blockchain Private Keys vs SSH Keys

The key question for mapping blockchain identity to git access is: how does an Ed25519 SSH key relate to a secp256k1 Ethereum key?

Key Type Curve Use Case alknet Derivation Path
Identity key Ed25519 SSH auth, node identity m/74'/0'/0'/0'
Device key Ed25519 Per-device identity m/74'/0'/0'/{n}'
SSH host key Ed25519 Server identity m/74'/0'/1'/0'
Encryption key AES-256-GCM External credential encryption m/74'/2'/0'/0'
Ethereum key secp256k1 Smart contract signing m/44'/60'/0'/0/0

The bridge: Both keys derive from the same BIP39 seed phrase. The secret service can sign an Ethereum transaction using the secp256k1 key and also authenticate SSH using the Ed25519 key. This creates a cryptographically linked identity pair:

  • On-chain identity (Ethereum address derived from m/44'/60'/0'/0/0)
  • Off-chain identity (Ed25519 key derived from m/74'/0'/0'/0')

Binding them: To prove that the Ed25519 key and the Ethereum key belong to the same entity:

  1. Sign a message with the Ed25519 key: "I, <Ed25519-pubkey>, attest that my on-chain identity is <Ethereum-address>"
  2. Store this attestation on-chain (in the org/user NFT metadata)
  3. Anyone can verify: the on-chain address owns the NFT, and the attestation links the SSH key to that address

This is the key binding mechanism that connects alknet's SSH-based authentication to on-chain identity.

6.3 Deriving Repository Access from On-Chain Identity

The complete flow for a push operation in a decentralized git system with on-chain ACL:

1. Client connects to replicator via SSH
2. SSH auth succeeds (Ed25519 key verified by alknet IdentityProvider)
3. Client pushes to repo X
4. Replicator checks:
   a. Local ACL metagraph: does this Ed25519 key have write access to repo X?
   b. If local ACL is stale, re-verify against on-chain contract
5. If authorized: accept push, gossip update to other replicators
6. If not: reject with "access denied"

Optimization: Step 4b is rarely needed if the local ACL cache is kept fresh via event subscriptions. The on-chain contract emits events on ACL changes, and the head node's sync process projects these into the local ACL metagraph.

alknet's existing support for this flow:

Component Role
IdentityProvider trait Resolves Ed25519 fingerprint → Identity with scopes/resources
ConfigIdentityProvider Local-only: reads from authorized_keys config
StorageIdentityProvider SQLite-backed: queries peer_credentials + ACL metagraph
OnChainIdentityProvider (future) Verifies against on-chain ACL, falls back to local cache
AuthProtocol (irpc) VerifyPubkeyIdentity resolution
CheckAccess (irpc) Identity + operation → access verification using ACL graph
OperationSpec.access_control Declarative access requirements per operation

7. Gossip Protocols for Repo Synchronization

7.1 Epidemic/Gossip Protocol Fundamentals

Gossip protocols are decentralized dissemination mechanisms inspired by how rumors spread in social networks. Key properties:

  • Eventual consistency: All nodes eventually receive all updates
  • Fault tolerance: Works even when nodes join/leave randomly
  • Scalability: O(log N) time to reach all nodes in a network of N nodes
  • No single point of failure: No coordinator node

7.2 Radicle's Gossip Protocol

Radicle uses three message types (detailed in Section 3.1):

  • Node Announcements: Peer discovery (who's online, where to reach them)
  • Inventory Announcements: Repo discovery (what repos each node seeds)
  • Reference Announcements: Update notifications (new commits, new COB operations)

Anti-entropy mechanism: Nodes periodically exchange state summaries to ensure they haven't missed any updates. This is similar to Merkle tree-based reconciliation in distributed databases.

Relevance to alknet: alknet's call protocol subscription model (call.requested with OperationType::Subscription) can serve as the transport for gossip messages. The key difference is that alknet's call protocol is request-response oriented, while gossip is push-based. A gossip layer on top of the call protocol would work as follows:

alknet gossip layer:
  1. Subscribe to `/{node}/gossip/announce` on known peers
  2. Receive NodeAnnouncement, InventoryAnnouncement, RefAnnouncement events
  3. Forward announcements to other connected peers (with deduplication)
  4. For RefAnnouncements of tracked repos, trigger git fetch

7.3 Alternative: CRDT-Based Sync

Instead of gossip + git fetch, some systems use CRDTs for repository synchronization:

  • Advantages: No merge conflicts, automatic convergence
  • Disadvantages: Large metadata overhead, complex implementation, doesn't map directly to git's object model

Recommendation for alknet: Start with gossip + git fetch (as Radicle does) and consider CRDT-based sync for specific metadata (e.g., ACL state, org metadata) while keeping git data as-is. The ACL metagraph changes can propagate via honker streams (which are effectively a form of CRDT merge).


8. Relevance to Alknet

8.1 Identity + IdentityProvider Model

alknet's existing Identity struct and IdentityProvider trait are already designed for this use case:

pub struct Identity {
    pub id: String,            // Fingerprint or UUID
    pub scopes: Vec<String>,   // Permission scopes
    pub resources: Option<HashMap<String, Vec<String>>>,  // Resource-level access
}

The id field serves dual purpose:

  • Config-based auth: SSH fingerprint (e.g., SHA256:abc123...)
  • Storage-based auth: Account UUID (e.g., acc_0123456789)

Extended for on-chain identity, the id field could also be:

  • On-chain auth: Ethereum address (e.g., 0x1234...) or NFT token ID (e.g., token_42)

The IdentityProvider trait naturally extends:

trait IdentityProvider: Send + Sync {
    fn resolve_from_fingerprint(&self, fingerprint: &str) -> Option<Identity>;
    fn resolve_from_token(&self, token: &[u8]) -> Option<Identity>;
}

// Future extension:
// OnChainIdentityProvider resolves Ethereum address + Ed25519 binding
// from on-chain ACL contract, with local metagraph cache

8.2 OperationRegistry Extension with On-Chain Verification

alknet's OperationSpec includes access_control fields:

pub struct AccessControl {
    pub required_scopes: Vec<String>,
    pub required_scopes_any: Option<Vec<String>>,
    pub resource_type: Option<String>,
    pub resource_action: Option<String>,
}

For on-chain verification, a new access_control mode could be added:

pub enum AccessControlMode {
    Local,           // Check against local ACL metagraph (current)
    OnChain,         // Verify against on-chain contract (future)
    CachedOnChain,   // Check local cache first, verify on-chain on miss/stale (recommended)
}

The AccessControl struct gains a mode field defaulting to Local. This is additive and doesn't change existing behavior.

8.3 Git Service Adapter for Decentralized Replication

alknet's application service pattern (from services.md) can accommodate a GitService:

#[rpc_requests(message = GitMessage)]
enum GitProtocol {
    #[rpc(tx=oneshot::Sender<RepoInfo>)]
    #[wrap(GetRepo)]
    GetRepo { repo_id: String },

    #[rpc(tx=oneshot::Sender<Vec<RepoInfo>>)]
    #[wrap(ListRepos)]
    ListRepos { org: Option<String> },

    #[rpc(tx=oneshot::Sender<bool>)]
    #[wrap(CanPush)]
    CanPush { repo_id: String, identity: Identity },

    #[rpc(tx=oneshot::Sender<()>)]
    #[wrap(UpdateMirror)]
    UpdateMirror { repo_id: String, refs: Vec<RefUpdate> },

    #[rpc(tx=mpsc::Sender<RefAnnouncement>)]
    #[wrap(SubscribeRefs)]
    SubscribeRefs { repo_ids: Vec<String> },
}

This service:

  • Registers with the call protocol as /head/git/*
  • Uses StorageIdentityProvider for CanPush checks (with ACL metagraph)
  • Manages git mirrors (git bare repos on the local filesystem)
  • Propagates updates via SubscribeRefs (which maps to honker stream subscriptions → call protocol integration events)

8.4 CredentialProvider Role

The existing CredentialProvider pattern in alknet (used for outbound authentication TO external services) maps to:

Use Case CredentialProvider Implementation
Push to GitHub/GitLab SSH key from alknet identity, or OAuth token from external source
Push to on-chain repo Ed25519 key derived from seed (signs the push) + Ethereum key (signs on-chain attestation)
Authenticate to replicator Ed25519 key (SSH auth via IdentityProvider)
Decrypt stored credentials AES-256-GCM key derived from seed via SecretProtocol

8.5 Domain Events vs. Integration Events (Distributed Git Context)

alknet's event boundary discipline (from event sourcing research and ADR-032) is critical for the distributed git scenario:

Event Type Source Consumer Boundary Git Analog
Domain events (honker) Local service Same service Internal Git object creation/update in local repo
Integration events (call protocol) Projected from domain events Other nodes/services Cross-node Push notification, gossip announcement
On-chain events (smart contract) Ethereum log Head node sync process External source ACL change on blockchain
Notifications (honker) Service Any subscriber Cross-service "Repo X was updated" (thin, ID-only)

The flow for a decentralized git push:

1. Client pushes to replicator
2. Replicator's GitService receives push
3. GitService publishes domain event: "repo:refs-updated" (honker stream)
4. Integration event projected: "call.responded" with repo update (call protocol)
5. Replicator gossips "RefAnnouncement" to tracked peers (call protocol subscription)
6. On-chain: if this push creates a new branch, optionally emit on-chain attestation
7. Peer replicators fetch updated refs (git protocol) and update their mirrors

The flow for an ACL change:

1. Org admin calls smart contract: grantWrite(repoId, newUserAddress)
2. Smart contract emits RoleGranted event
3. Head node's sync process detects the event (Ethereum log subscription)
4. Sync process calls StorageService: add DelegatesEdge to ACL metagraph
5. StorageService publishes domain event: "acl:updated" (honker stream)
6. Integration event projected: notify replicators of ACL change (call protocol)
7. Replicators update their local ACL cache

This cleanly separates:

  • On-chain events (smart contract logs) = external source of truth
  • Local projections (ACL metagraph) = cached view for fast access checks
  • Integration events (call protocol) = cross-node notification mechanism
  • Domain events (honker streams) = internal state management

8.6 Practical Integration Path

For alknet to support the decentralized git concept, the integration path is:

Phase 1: Foundation (Current Architecture)

  • IdentityProvider trait supports multiple backends ✓
  • StorageIdentityProvider queries peer_credentials + ACL graph ✓
  • SecretProtocol derives Ed25519 and secp256k1 keys from same seed ✓
  • OperationSpec.access_control supports scope-based checks ✓

Phase 2: Git Service (Additive)

  • Add GitProtocol irpc service for repo management
  • Implement GitService as an application service (like DockerService, NodeService)
  • Map CanPush to ACL metagraph traversal
  • Implement pre-receive hook that calls alknet's CheckAccess irpc

Phase 3: On-Chain ACL (Additive, Requires External Dependencies)

  • Add OnChainIdentityProvider that:
    1. Resolves Ed25519 fingerprint → Ethereum address (via attestation stored in NFT metadata)
    2. Checks on-chain ACL contract for access rights
    3. Caches results in local ACL metagraph
    4. Subscribes to on-chain events for ACL changes
  • Add AccessControlMode::CachedOnChain to OperationSpec
  • Add WalletProtocol irpc service for signing on-chain transactions

Phase 4: Gossip and Replication (Additive)

  • Add gossip message types to call protocol (NodeAnnouncement, RepoAnnouncement, RefAnnouncement)
  • Implement SubscribeRefs streaming operation for repo update subscriptions
  • Add replicator service that seeds repos and responds to gossip

Each phase is additive and doesn't require changes to earlier phases. The architecture supports this incremental extension because:

  1. IdentityProvider is a trait — new implementations are additive
  2. OperationSpec.access_control is a struct — new fields are additive
  3. Application services register with the call protocol — new services don't change core
  4. Honker streams are internal — new streams are additive

9. References

Decentralized Git Platforms

Blockchain Identity and Naming

Access Control

Cryptographic Key Management

  • SLIP-0010: https://slips.readthedocs.io/en/latest/slip-0010/ — Universal private key derivation from master private key (Ed25519, secp256k1, NIST P-256)
  • BIP-0032: Hierarchical Deterministic Wallets
  • BIP-0039: Mnemonic code for generating deterministic keys
  • SLIP-0044: Registered coin types for BIP-0044 (alknet uses unallocated 74')
  • Ed25519: Bernstein's Edwards-curve Digital Signature Algorithm

Gossip Protocols

Alknet Architecture Documents (Internal)

  • core.md: Transport, call protocol, auth, services, DNS
  • services.md: irpc service architecture, OperationEnv, Identity, auth/secret/config protocols
  • storage.md: Metagraph data model, ACL as metagraph, identity tables, honker integration
  • integration-plan.md: Phase 0-4 integration plan, ADRs 026-034
  • ADR-029: Identity as core type (Identity { id, scopes, resources } + IdentityProvider trait)
  • ADR-032: Event boundary discipline (domain events vs. integration events vs. service calls)

Radicle-Specific Documentation