NAOMS for developers

← Back to overview

Build & ship · Step 2

Connect by asking

There is no login form and no place to paste a recovery phrase. An app gets access by asking for exactly the scope it needs and having a person approve that request on a device they already trust.

Connect by asking is how an outside app gets access to NAOMS. The app registers the exact capability scope it needs, a person approves that specific request on a device they already trust, and NAOMS encrypts a freshly minted key, scoped to only what was granted, to the app’s own throwaway keypair. The app never sees the owner’s real identity key.

What a person notices

An approval card names the app and the exact permission it asked for, for example read-only access to part of their graph. Nothing broader is offered.

They can approve or deny from whichever device they're already on: a phone, a browser, or a command line.

The request expires on its own if nobody acts on it, so a forgotten request cannot be approved by accident much later.

What you do as a developer

This is the same approval mechanism the platform's own command line uses to mint its own keys, applied equally to outside apps.

1

Register and name the scope you want

Your app calls a register function with the address of the NAOMS app on your device, an app name and version, and the capability scope it actually needs. This generates a throwaway keypair locally and sends the request, getting back a pending approval id.

2

Wait on the approval

Your app polls for a result while the owner decides. There is nothing for your app to do but wait; it never sees the owner's real key at any point.

3

Receive a key scoped to exactly what was granted

On approval, NAOMS encrypts a freshly minted key to your app's throwaway keypair so the plaintext key is never sent in the open, and your app decrypts it locally. That new key is scoped to the capability actually granted, never the owner's own identity key.

4

Connect with it

Pass that key straight into the client connection call. From here on, it is what authenticates your app's connection to NAOMS.

Ask for the narrowest scope your app needs. The permission to approve or deny other requests is not handed to third-party apps by default, and there is no ordinary reason for your app to ask for it.

The shape of a real registration and connection call:

// Register asks for a scope and waits for a person to approve it on a
// device they already trust.
const creds = await register({
  daemonHttpUrl: "http://127.0.0.1:3147",
  appVersion: "0.1.0",
  capabilities: ["graph.query"],
  onApprovalPending: (info) =>
    console.log(
      `Open ${info.approvalUrl} and approve within ${info.expiresIn}s`,
    ),
});

// creds.childSecret is the app's own key, scoped to what was granted --
// never the owner's real identity key.
const client = await NaomsClient.connect({
  url: "ws://127.0.0.1:3147/ws",
  secretKey: creds.childSecret,
});

How it relates to other steps

Build

Your package's manifest declares the capabilities it needs; a package that runs inside the platform gets its scoped access this way automatically, without writing this flow itself.

Package

An app that runs outside the platform and talks to NAOMS from the outside is exactly the case this flow is for.