Credential Revocation
Last updated
Was this helpful?
When a scout leaves a troop or their credential needs to be invalidated, ScoutPass uses LearnCard's revocation system to cleanly remove access while preserving audit history.
Revocation is tracked via a status property on the Neo4j CREDENTIAL_RECEIVED relationship:
null
Active/claimed credential
'pending'
Sent but not yet accepted
'revoked'
Credential has been revoked
When a credential is revoked:
The credential is marked as revoked (not deleted) for audit purposes
The scout is filtered out of member/recipient lists
Any permissions granted via claim hooks are reversed
Any auto-connect relationships are cleaned up
The scout's wallet syncs to remove the credential from view
When revocation occurs, these cleanup operations run automatically:
processPermissionsRevokeHooks
Removes roles granted via GRANT_PERMISSIONS claim hooks
processAutoConnectRevokeHooks
Removes AUTO_CONNECT_RECIPIENT relationships
processAdminRevokeHooks
Removes admin roles granted via ADD_ADMIN claim hooks
processConnectionRevoke
Removes CONNECTED_WITH relationships sourced from the boost
All recipient queries automatically exclude revoked credentials:
getBoostRecipients
Returns only claimed credentials
countBoostRecipients
Counts only claimed credentials
Note: Revoked credentials are always filtered out, regardless of query options.
The scout's wallet syncs with the network to remove revoked credentials using the useSyncRevokedCredentials hook:
This hook:
Fetches revoked URIs from wallet.invoke.getRevokedCredentials()
Removes matching records from the LearnCloud personal index
Invalidates UI queries to refresh the display
Credentials exist in two places:
Brain Service (Neo4j)
Network-level tracking, source of truth for status
LearnCloud (MongoDB)
User's personal wallet, what shows in the app
The brain service cannot directly modify the user's LearnCloud index (it's user-authenticated). The frontend sync hook bridges this gap.
Boost Credentials — Boost hierarchy and permissions
Credential Lifecycle — Full credential lifecycle
Last updated
Was this helpful?
Was this helpful?
MATCH (c:Credential)-[r:CREDENTIAL_RECEIVED]->(p:Profile)
WHERE (r.status IS NULL OR r.status <> 'revoked')
RETURN pimport { useSyncRevokedCredentials } from 'learn-card-base';
// In AppRouter.tsx or top-level component
useSyncRevokedCredentials(enabled);