-
Notifications
You must be signed in to change notification settings - Fork 19
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
DloD: DDB's list of Death #108
Comments
Copying the gist below for posterity. User Stories
Progress on Each
The dApp-Orbit integration work involves data modeling. The implementation is The pinningService is mostly complete. It is ready to be improved through usage. The solution to keys is WIP. We have ideas but they are not yet proven. Dynamic database permissions has several suggested implementations, but is not 1. KeysKeystore
IPFS-log interface to contract and DDB
Generating keysWalletsFrom Thiago's Notes: Wallets we need to cater for specifically
Generating keys, notes from Thiago's research
2. PermissionsOrbitDB issueDSGuard Contractshamb0t's exampleAccess ControllerLaurent's planPermissions Model
3. ArchitectureThis architecture, once fully understood, largely explains the proposed changes :-) OrbitDB.js uses ipfs-access-controller (which inherits from access-controller) to create and save into IPFS an access-controller.
Further Notesipfs-log/log.js, log.append, checks for write permissions. It doesn't verify, but decorates the entry. ipfs-log/log.js, log.join, checks for write permissions, and also verifies each entry.
4. Plan of AttackPermissions
Keystore and Keys
5. Future Database ChangesOrbit
Colony
|
Laurent's Gist on OrbitDB Permissions for posterity. The idea of dogfooding for permissions One limitation I see is that it limits us to using orbitdb-backed approach, which might For example, we would like to:
A simple approach would be to let app developpers customize the Could orbitdb implement an inversion of control / middleware approach to let us define different permission protocols? the IPFS manifest and the (wip) store approaches would be provided as default middlewares. Auth-related code would be refactored out of orbitdb ipfs-logs to separate concerns more clearly:
The access middleware would look something like:
A few practical examples: Scenario: Allow everything. class AccessControllerAllowAll {
this.isWriteAllowed = async (entry) => true
this.decorateEntry = async (entry) => entry
} Scenario: Allow based on ipfs manifest: class AccessControllerIPFSManifest {
constructor(key, ipfs, manifestAddress) {
this.keyStore = keyStore;
this.manifest = await loadManifest(ipfs, manifestAddress)
}
async isWriteAllowed(entry) {
if (!this.keyStore.verify(entry, entry.signature) === entry.key) {
return false; // wrong signature
}
// manifest allows this key
return (this.manifest.writes.include('*') || this.manifest.writes.include(entry.key));
}
async decorateEntry(entry) {
entry.key = this.keyStore.publicKey;
entry.signature = this.keyStore.sign(entry);
}
} Scenario: Allow writes depending on roles defined on chain. class AccessControllerAllowFromBlockchain {
async isWriteAllowed(entry) {
if (!(await myBlockchainAPI.isUserAdmin(entry.key))) {
return false;
}
return this.keyStore.verify(entry, entry.signature) === entry.key;
}
decorateEntry: (entry) => {
entry.key = this.keyStore.publicKey;
entry.signature = this.keyStore.sign(entry);
return entry;
} Scenario: We want roles defined on-chain: "I'm the owner of a Colony", "I'm the owner of a user ID". For this we'd need to verify that a payload was signed by a key ( const AccessControllerWithChildKeys {
constructor(rootKeyStore) {
this.localKeyStore = generateKeyPairs();
this.localKeySignature = rootKeyStore.sign(this.childKeyStore.publicKey); // happens once
}
async isWriteAllowed(entry) {
// Check the payload was signed by a given local key
const verified = this.localKeyStore.verify(entry, entry.signature) === entry.key;
if (!verified) {
return false;
}
// Check that the local key was signed by the owner of a ressource on chain
const globalKey = this.keyStore.verify(entry.key, entry.rootSignature);
return (await myBlockchainAPI.isUserAdmin(globalKey))
}
async decorateEntry(entry) {
entry.key = this.keyStore.publicKey;
entry.signature = this.localKeyStore.sign(entry);
entry.rootSignature = this.localKeySignature;
return entry;
}
} We'd pass a controller, either as an instance, or as a factory (that takes function myStore() {
const accessController = new AccessControllerWithChildKeys(rootKeyStore);
const store = orbitdb.kvstore({accessController});
} This would let us:
Limitations:
Code change (WIP):
|
Thiago notes.md Wallets we need to cater for specifically
NOTE: We can’t plug in a wallet into orbit. Taking actions to sign every entry, it’d be a terrible experience for users and we need to be able to revoke keys, doing that per ethereum account would get pretty annoying too. Permissions
NOTE: In the case that ethereum node isn’t up-to-date, it might be necessary to put new entries in some kind of queue to be retried later otherwise they’d get invalidated NOTE2: Is it possible for us to have a contract that just generates a unique id per entry and sign it if the wallet plugged to the contract is allowed to do the change? NOTE3: orbit-db-keystore, ipfs-log and access controllers should be changed. ipfs-log shouldn’t know about keystore implementation details (use sign and verify functions passed via constructor to the log instead), the keystore has a few unused methods, the access controller should get the keystore and interface with the ipfs-log instead of passing the keystore to the log KeysNOTE: Currently, orbit stores users keys on the localStorage. That needs to change! In the ideal scenario, we generate a master-key from an ethereum account that will be used to manage permissions on the blockchain and that master-key generates child keys that are used to sign entries on orbit (per db instance or per dapp)
|
This is the minimum set of issues we gotta close to use orbit the way we intend to
Please see this gist for a more complete breakdown. In particular, section 3 explains the architecture
The text was updated successfully, but these errors were encountered: