- 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
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
- Executive Summary
- Source Concept: NFT-Based Decentralized Git
- Existing Projects
- Identity on the Blockchain
- Access Control Models for Distributed Git
- Cryptographic Identity Mapping
- Gossip Protocols for Repo Synchronization
- Relevance to Alknet
- 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:
-
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.
-
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
StorageIdentityProviderapproach. -
alknet's BIP39/SLIP-0010 key derivation already spans both worlds. The
m/74'/0'/0'/0'path for Ed25519 identity andm/44'/60'/0'/0/0for Ethereum signing means the same seed phrase that governs alknet authentication can also sign on-chain transactions — no separate wallet needed. -
The Identity + IdentityProvider model maps directly to decentralized identity.
ConfigIdentityProvideris the local-only mode (Radicle-like);StorageIdentityProvideris the cached mode (on-chain ACL mirrored to SQLite); a futureOnChainIdentityProvidercould verify against smart contracts. -
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:
- Performance: IPFS retrieval is slower than centralized git hosting
- UX: Browser-based git clients lack feature parity with CLI tools
- 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 →
PrincipalNodein alknet's ACL metagraph collaboratorsmapping →DelegatesEdgewithnarrowed_scopescanPush()→ alknet'scheck_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.idtext record → alknet Node ID (Ed25519 public key fingerprint)alk.pubkeytext record → Ed25519 public key (for SSH authentication)alk.replicatortext 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):
- Smart contract emits
RoleGranted(address, repoId, role)event - alknet head node listens to these events (via Ethereum log subscription)
- Event is projected into the ACL metagraph as a
DelegatesEdgewithnarrowed_scopes - Local access checks use the metagraph (fast, SQLite)
- 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_keysmaps SSH keys to Gitolite users~/.gitolite/conf/gitolite.confdefines 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:
- Sign a message with the Ed25519 key:
"I, <Ed25519-pubkey>, attest that my on-chain identity is <Ethereum-address>" - Store this attestation on-chain (in the org/user NFT metadata)
- 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) |
VerifyPubkey → Identity 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
StorageIdentityProviderforCanPushchecks (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)
IdentityProvidertrait supports multiple backends ✓StorageIdentityProviderqueriespeer_credentials+ ACL graph ✓SecretProtocolderives Ed25519 and secp256k1 keys from same seed ✓OperationSpec.access_controlsupports scope-based checks ✓
Phase 2: Git Service (Additive)
- Add
GitProtocolirpc service for repo management - Implement
GitServiceas an application service (like DockerService, NodeService) - Map
CanPushto ACL metagraph traversal - Implement
pre-receivehook that calls alknet'sCheckAccessirpc
Phase 3: On-Chain ACL (Additive, Requires External Dependencies)
- Add
OnChainIdentityProviderthat:- Resolves Ed25519 fingerprint → Ethereum address (via attestation stored in NFT metadata)
- Checks on-chain ACL contract for access rights
- Caches results in local ACL metagraph
- Subscribes to on-chain events for ACL changes
- Add
AccessControlMode::CachedOnChaintoOperationSpec - Add
WalletProtocolirpc service for signing on-chain transactions
Phase 4: Gossip and Replication (Additive)
- Add gossip message types to call protocol (
NodeAnnouncement,RepoAnnouncement,RefAnnouncement) - Implement
SubscribeRefsstreaming 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:
IdentityProvideris a trait — new implementations are additiveOperationSpec.access_controlis a struct — new fields are additive- Application services register with the call protocol — new services don't change core
- Honker streams are internal — new streams are additive
9. References
Decentralized Git Platforms
- Radicle Protocol Guide: https://radicle.dev/guides/protocol — Comprehensive documentation of Radicle's identity system, gossip protocol, replication, and self-certifying repositories
- Radicle Heartwood (source): https://github.com/radicle-dev/heartwood — Reference implementation in Rust
- RIP-0002 Identity: Radicle Improvement Proposal for identity documents and delegate thresholds
- radicle-crypto crate: Ed25519 key types, SSH encoding, keystore (DeepWiki analysis: https://deepwiki.com/radicle-dev/heartwood/7.1-radicle-crypto)
- ForgeFed: https://forgefed.org/ — ActivityPub-based federation protocol for forges (Forgejo, Gitea integration)
- GitLike: https://gitlike.dev/ — Browser-based decentralized VCS using IPFS and Ethereum
- GitBross: https://gitbross.com/ — Decentralized Git platform using Solana, Arbitrum, and IPFS
- PineSU: IEEE paper on Git + Ethereum integration for trusted information sharing
Blockchain Identity and Naming
- ERC-721 Standard: https://ethereum.org/developers/docs/standards/tokens/erc-721 — Non-fungible token standard
- ENS (Ethereum Name Service): https://docs.ens.domains/ — Decentralized naming on Ethereum
- W3C DID Primer: https://w3c-ccg.github.io/did-primer/ — Decentralized Identifiers overview
- W3C Verifiable Credentials: https://www.w3.org/TR/vc-data-model/ — VC specification
- EIP-3668 (CCIP-Read): Off-chain data lookup for ENS, enabling smart contracts to verify off-chain data
Access Control
- Git Hooks: https://git-scm.com/book/en/v2/Customizing-Git-Git-Hooks — Server-side hooks for git access control
- Gitolite: Config-file-based SSH key → repo permission mapping
- Token-Gated Access Control: https://chainscorelabs.com/guides/ — Patterns for ERC-721/ERC-1155 token-gated access
- ChainGuard: Blockchain-based authentication and access control (academic paper)
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
- Gossip Protocol Fundamentals: https://www.geeksforgeeks.org/distributed-systems/gossip-protocol-in-disrtibuted-systems/ — Epidemic-style information dissemination
- libgossip: C++17 implementation for decentralized node discovery and metadata propagation
- Bitcoin Gossip: Used in Bitcoin for transaction and block propagation
- Secure Scuttlebutt (SSB): Inspiration for Radicle's gossip model
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 }+IdentityProvidertrait) - ADR-032: Event boundary discipline (domain events vs. integration events vs. service calls)
Radicle-Specific Documentation
- Radicle COBs (Collaborative Objects): CRDT-based distributed issues/patches stored as Git objects — https://deepwiki.com/radicle-dev/heartwood/6.1-collaborative-objects-(cobs)
- Radicle Identity Documents: Delegates, thresholds, and self-certifying repo identity — RIP-0002
- Radicle Signed Refs: Vulnerability disclosure (2026-03) on replay attacks in signed references