Skip to main content
TinyCloud uses two distinct types of Decentralized Identifiers (DIDs) for different purposes. Understanding when to use each is critical for successful delegations and correct identity handling.

The Two DID Types

Session Key DID

The Session Key DID is an ephemeral identifier generated fresh for each session. It uses the did:key method:
did:key:z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK#z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK
This DID represents the cryptographic key that signs requests to the TinyCloud server during a single session. It is rotated on each authentication and should never be used for persistent identity. Access it via .sessionDid:
const sessionDid = tc.sessionDid;
// Returns: did:key:z6Mk...#z6Mk...

Primary DID (User Identity)

The Primary DID represents the user’s persistent identity, derived from the authentication method they used. For Ethereum wallets, this is a did:pkh (Public Key Hash) DID:
did:pkh:eip155:1:0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045
This DID remains constant as long as the user uses the same wallet address. It is the correct identifier for user-to-user relationships and delegations.

The .did Property

The tc.did property returns different values depending on the authentication state:
After calling signIn(), tc.did returns the primary DID (persistent identity):
await tc.signIn();

console.log(tc.did);
// did:pkh:eip155:1:0xd8dA...6045 (primary DID)

console.log(tc.sessionDid);
// did:key:z6Mk...#z6Mk... (session key DID)
In this mode, tc.did and tc.sessionDid return different values. Use tc.did for delegations and identity, and tc.sessionDid for debugging session internals.

When to Use Which

Use CaseWhat to UseReturns
User-to-user delegationstc.didPrimary DID (after signIn)
Identifying a user persistentlytc.didPrimary DID (after signIn)
Debugging session key issuestc.sessionDidSession Key DID
Logging internal session statetc.sessionDidSession Key DID
After signIn(), use tc.did for delegations. It returns the primary DID, which is what the server expects. Use tc.sessionDid only when you need to inspect the ephemeral session key for debugging.

The Common Mistake

When Alice wants to delegate capabilities to Bob, developers sometimes use the session DID directly instead of the primary identity:
// WRONG - using sessionDid for delegations will fail server validation
await alice.createDelegation({
  delegateDID: bob.sessionDid,  // Session key DID - ephemeral!
  abilities: ["tinycloud.kv/get", "tinycloud.kv/put"]
});
// Error: "Delegation failed: invalid delegatee"
The correct approach:
// CORRECT - use tc.did (which returns primary DID after signIn)
await alice.createDelegation({
  delegateDID: bob.did,  // Primary DID after signIn
  abilities: ["tinycloud.kv/get", "tinycloud.kv/put"]
});
This is the #1 pitfall in TinyCloud SDK usage.After signIn, the .did property returns your primary DID. This is the DID others should use when creating delegations to you. A delegation targeting a session key DID will always fail because:
  1. The server expects the primary DID format for the delegatee field
  2. Session DIDs are ephemeral and rotate on each authentication
  3. A delegation to Bob’s session DID becomes invalid the moment Bob re-authenticates

Why This Matters

The TinyCloud server performs strict validation on delegation chains:
  1. Delegatee matching: When Bob uses a delegation from Alice, the server checks that the delegatee field in Alice’s delegation matches Bob’s identity
  2. Primary DID expected: The server expects the delegatee to be the primary DID (e.g., did:pkh:eip155:... for Ethereum wallets)
  3. Session DIDs are ephemeral: Bob’s session DID changes with each authentication, so a delegation to bob.sessionDid would be invalid after Bob re-authenticates
The primary DID remains constant as long as Bob uses the same authentication method (e.g., same wallet address), making it the correct identifier for persistent user-to-user relationships.

Quick Reference

// After signIn():
console.log("User identity (for delegations):", tc.did);
// -> did:pkh:eip155:1:0xabc... (primary DID)

console.log("Session key (for debugging):", tc.sessionDid);
// -> did:key:z6Mk...#z6Mk...

// Summary:
// tc.did        = Primary DID after signIn, session DID before signIn
// tc.sessionDid = Always session key DID
If you see the error “Delegation failed: invalid delegatee”, verify that you are using tc.did (after signIn()) rather than tc.sessionDid when specifying the delegate.