Identity and access
Jnu never asks for a database password. Every query is signed by an identity, the service resolves that identity to the account it acts for, and a per-table security policy decides which rows and columns that account may see or change. This page explains the three pieces: identities and proxy keys, the ownership rules, and how to make a key that can do exactly one thing.
Who signs the query
jnu.connect(service, keystore) signs every query with keystore. Without the second argument it waits for a dcp/identity session and uses that, which is how browser pages and the <jnu-record-set> element work.
The signing address is usually a proxy key: an API key created in the Portal, or a session key issued by identity.login(). The pxAuth service maps the key’s address (proxyAddress) to the account it acts for (authAddress), and the policy is evaluated for the account. A job deployed with an API key is owned by the account, not the key, so any other key of the same account that carries the right operations can see it. A plain private key that isn’t registered as a proxy acts for itself.
Ownership
Each policy names an owner column, directly or through another table:
Direct:
jobs.owner,computeGroups.owner,worker.owner,credsList.owner, and theownercolumn of every Portal table. You see rows whose owner is your account.Via a job:
jobPerfData,jobFinData,activeSlices,jobResults,jobData,jobArguments,workFunctions,workRejectHistory,computeGroupsJobs_byJob. You see rows whose job you own.Via a Compute Group:
computeGroupJobs,computeGroupAccountingData,computeGroupWorkerOrigins,computeGroupJobPeriodStats,computeGroupWorkerPeriodStats. You see rows for groups you own.World:
jobs_publicandcomputeGroups_publicreturn a few public columns to any identity.
The policy also fixes which columns a change may touch. For jobs that’s name, description and link only; as of 2026-10-03 the slice price, status and everything else are read-only through Jnu, so changing the price of a running job means cancelling and redeploying. The per-table details are on the scheduler, portal and proxy key pages.
A query you’re not allowed to make fails with Invalid operation <service>.jnu.<table>.query. A query you’re allowed to make that would return rows belonging to someone else returns nothing.
Operations a key needs
Every Jnu call is authorized against one operation key of the form <service>.jnu.<table>.<action>, where the action is query, change, delete, add, add.simple or add.changeMiss. Parent keys grant their children: scheduler.jnu.jobs grants all actions on jobs, scheduler.jnu grants every table, and $login grants everything.
To do this |
The key needs |
|---|---|
Read your jobs and their progress |
|
Read everything about your jobs |
add |
Rename a job or change its description or link |
|
Point slice inputs or results to new storage |
|
Administer a Compute Group |
|
Manage your workers |
|
Read your Portal profile and preferences |
|
The job levers that aren’t Jnu calls need their own operations: job.close to pause and resume, job.cancel, job.computeGroup.add to add a running job to a group, job.results.fetch to download results, and job.exec to deploy. A key with job.exec is automatically allowed the other job.* operations on the jobs it deployed.
Making a key in the Portal
The Keys page of the Portal creates keys with a purpose, which is a preset bundle of operations:
Purpose |
Operations |
Good for |
|---|---|---|
|
|
Deploying from scripts. Can’t read the database. |
|
|
Pausing, cancelling and fetching results. Can’t read the database. |
|
|
Read-only dashboards and reports: every table, no job levers. |
|
|
Wallet operations. Handle with care. |
|
|
Everything above. Use it for development, not for deployment. |
Within a purpose, each operation can be narrowed before the key is created:
Expiry and uses: every row has an expiry date, and an operation can be limited to a number of uses.
A job: job operations can be tied to one job (
relatedbecomesjob-<opaqueId>).A where clause:
jnuoperations can be tied to rows matching a JSON prototype. The Portal shows an editor for it and validates the columns against the table. For example,scheduler.jnu.jobs.querywith{"status":"running"}lets the key see running jobs only, andscheduler.jnu.jobResults.querywith{"jobId": 389798}lets it read one job’s results and nothing else. The clause is merged into every query the key makes, so it can’t be bypassed from the client.
A key built this way is what to hand to a third-party service, a CI pipeline or a public dashboard: it can read exactly the rows it’s meant to and nothing else, and deleting its rows from proxyAuth revokes it.
Note
Keys are passphrase-protected keystore files when downloaded. In code, identity.set('<private key>') or new wallet.Keystore(json, passphrase) turns one into an identity. Treat the private key as the credential: anyone holding it can do whatever the key’s operations allow until it expires or is revoked.