Skip to content
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

Add core ownership records #175

Closed
4 of 7 tasks
Tracked by #189 ...
gmaclennan opened this issue Aug 15, 2023 · 1 comment · Fixed by #214, #229 or #230
Closed
4 of 7 tasks
Tracked by #189 ...

Add core ownership records #175

gmaclennan opened this issue Aug 15, 2023 · 1 comment · Fixed by #214, #229 or #230
Assignees

Comments

@gmaclennan
Copy link
Member

gmaclennan commented Aug 15, 2023

Description

Each device is identified by an "identity key". We need to know which cores belong to which device. Each device should own at most one core in each namespace, and at least one core in the 'auth' namespace.

So that we can use our existing indexer, we can use the device identity public key as docId. The other fields need to be:

type CoreOwnership = {
  authCoreId: string,
  configCoreId: string,
  dataCoreId: string,
  blobCoreId: string,
  blobIndexCoreId: string
}

e.g. fields names of the format ${namespace}CoreId.

The authCoreId should always match the core ID of the auth core where it is written.

Validation

To validate this message, we need to validate ownership of the secret keys for each core. We can store this in a signature record, where we sign the core keys (as buffers), using the core secret key.

type CoreOwnership = {
  // ...
  coreSignatures: Record<Namespace, Buffer>

We don't need to convert these to string because we don't need to use them in any SQL queries (unlike the coreId fields above). That saves a round-trip from buffer-string-buffer.

We also need to validate ownership of the identity key - unlikely that someone would say their cores belong to someone else, but maybe best to be sure?

type CoreOwnership = {
  // ...
  identitySignature: Buffer
}

Questions

  • Should we allow core ownership records to be modified? If not we can "trick" sqlite-indexer to only index the first ownership record by:
    1. Before sending to the indexer (e.g. in IndexWriter) check the authCoreId matches the core where it is written
    2. Replace links with an empty array
    3. Pass a custom getWinner function to sqlite-indexer to pick the winner with the lowest index (from versionId)
  • Should we validate at index time or at read time? Might make sense to keep the validation in the indexer, then we only need to validate once rather than on every read. Should just drop/ignore invalid records.
  • Where should responsibility for writing the core ownership record lie? It should happen when the auth core is first created. Maybe in CoreManager?

API

class CoreOwnership {
  constructor({
    coreManager: CoreManager,
    authDataStore: DataStore,
    keyManager: KeyManager
  })
  // Write the ownership record to the auth core.
  writeOwnership(): Promise<void>
  // Return the identity key of the device that owns the core with the given key
  getOwner(coreKey: Buffer): Promise<Buffer>
  // Return the core key for the core owned by deviceId in the given namespace
  getCoreKey(deviceKey: Buffer, namespace: Namespace): Promise<Buffer>
}

Tasks

@achou11
Copy link
Member

achou11 commented Aug 21, 2023

Should we allow core ownership records to be modified?

Don't have any useful input on this one. Just reading about the "trick" doesn't seem inspiring from a code maintenance perspective, but not sure what allowing modifications entails in practice.

Should we validate at index time or at read time?

Leaning towards at index time

Where should responsibility for writing the core ownership record lie?

CoreManager seems to make sense 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment