Skip to content

Permission Model

NOOSChain is a permissioned system. Actions are performed by known actors, and bucket access is granted to explicit principals.

The permission model has two layers:

  • Actor resolution answers: who is performing this action?
  • Bucket permissions answer: what is that actor allowed to do to this bucket?

Permissions are consensus-state rules. API checks improve read security and error messages, but deterministic block execution is authoritative.

Actors And Principals

An actor is the resolved identity performing an operation.

A principal is an identity that can be named in a bucket access rule.

Most of the time they line up, but the distinction matters for contracts and organizations. A signed user transaction resolves to a user actor; that user may also receive permissions through an organization principal. A smart contract call resolves to a contract actor during contract execution; the contract must have its own bucket access rule for sensitive bucket host calls.

System Actor

GENESIS and system execution can perform genesis/system operations. These paths are special and should not be treated as ordinary user authorization.

Normal application and operator workflows should use signed transactions from registered users.

Users

Users are identity-bearing actors with public keys. Execution derives authority from transaction.envelope.signerPublicKey, not from untrusted payload fields.

The signer public key maps deterministically to a user. That user's organization comes from chain state.

For non-system bucket creation and encrypted-record writes, creator fields in the payload must match the resolved signer user and organization.

Organizations

Organizations group users and can receive bucket permissions as principals.

An organization bucket access rule applies to every actor in that organization. For example, granting bucket:read_metadata to organization org-noos allows users in org-noos to read bucket and record metadata.

Organization membership also matters for bucket-key envelope recipient selection and for node replication policies.

Nodes

Nodes run NOOSChain software. Validator nodes participate in consensus; observer nodes sync and serve read-oriented workflows.

Nodes are not ordinary bucket access-rule principals in the same way users, organizations, and contracts are. For node-to-node replication, verified node membership and the bucket replication policy decide whether a node may receive ciphertext and, for per_bucket_key buckets, matching bucket-key envelope metadata.

Contracts

Smart contracts can act as contract principals after they are deployed and instantiated.

A contract principal is not a normal user and does not sign transactions directly. It is resolved from contract instance consensus state during contract execution and has a contract id, organization id, and owner user id.

For sensitive bucket host calls, two things must line up:

  • The contract manifest must declare the bucket access the method requires.
  • The bucket must grant matching permissions to the contract principal.

Bucket Owners

The bucket creator user and creator organization have implicit bucket:admin. This implicit admin is part of bucket state.

Because owner admin is implicit, removing an explicit admin rule does not remove admin from the bucket creator user or creator organization.

Explicit Access Rules

Bucket access rules grant permissions to:

  • user
  • organization
  • contract

Access rules are changed through protocol-versioned transactions:

  • ADD_BUCKET_ACCESS_RULE
  • UPDATE_BUCKET_ACCESS_RULE
  • REMOVE_BUCKET_ACCESS_RULE

All three require bucket:admin on the target bucket, except for system/genesis operations.

Permission lists are normalized before storage and state hashing. Duplicates are removed, strings are sorted, and unknown permissions are rejected. Empty updates are invalid; remove the rule instead.

Permission Evaluation

NOOSChain evaluates bucket permissions deterministically:

  1. System actor.
  2. Implicit bucket owner/admin.
  3. Direct user or contract access rule.
  4. Organization access rule.

bucket:admin implies every other bucket permission.

Bucket Permissions

NOOSChain currently defines four bucket permissions.

bucket:read_metadata

Allows the principal to view bucket metadata and record metadata/indexes.

This is required for:

  • Reading bucket details.
  • Searching records by public indexes.
  • Inspecting record metadata.

It does not allow encrypted payload bytes to be returned.

bucket:read_encrypted

Allows the principal to receive encrypted payload bytes when the payload is available and the bucket policy permits it.

This does not decrypt data by itself. The actor still needs matching key material, such as a record key envelope or bucket-key envelope, and the corresponding private key or KMS/HSM capability.

Removing bucket:read_encrypted blocks future authorized API reads for that principal. It does not rewrite historical records or automatically delete ciphertext already stored locally.

bucket:write

Allows the principal to add encrypted records.

ADD_ENCRYPTED_RECORD requires bucket:write. Creator fields must match the signer unless the actor is system. Public index validation and encrypted payload state hashing still apply.

bucket:admin

Allows the principal to administer the bucket.

bucket:admin is required to:

  • Add access rules.
  • Update access rules.
  • Remove access rules.
  • Update mutable bucket policy fields.
  • Create or rotate bucket keys for per_bucket_key buckets.

It implies bucket:read_metadata, bucket:read_encrypted, and bucket:write.

Permissions Do Not Decrypt Data

Bucket permissions decide whether APIs and execution paths may expose metadata, return encrypted bytes, write records, or administer rules.

They do not decrypt payload data. Decryption is explicit and depends on key envelopes, private keys, bucket keys, or future KMS/HSM-backed key operations.

This separation is important:

  • bucket:read_metadata can reveal searchable metadata without payload bytes.
  • bucket:read_encrypted can reveal ciphertext without plaintext.
  • Key envelopes can make data decryptable only to intended recipients.
  • Replication policy can control which nodes retain ciphertext locally.

Create Principals

Principals are created through normal chain transactions.

Create An Organization

Generate a template:

powershell
npm run noos -- recipe init:template organization --output org.json

Create the organization transaction:

powershell
npm run noos -- recipe init:create-organization `
  --payload-file org.json `
  --signer-public-key="<admin-public-key>" `
  --signer-private-key-path admin.key `
  --yes

Raw transaction form:

powershell
npm run noos -- tx build `
  --type REGISTER_ORGANIZATION `
  --payload-file org.json `
  --signer-public-key="<admin-public-key>" `
  --signer-private-key-path admin.key `
  --output org-tx.json

npm run noos -- tx submit --file org-tx.json --yes

Create A User

Generate a template:

powershell
npm run noos -- recipe init:template user --output user.json

Create the user transaction:

powershell
npm run noos -- recipe init:create-user `
  --payload-file user.json `
  --signer-public-key="<admin-public-key>" `
  --signer-private-key-path admin.key `
  --yes

Raw transaction form:

powershell
npm run noos -- tx build `
  --type REGISTER_USER `
  --payload-file user.json `
  --signer-public-key="<admin-public-key>" `
  --signer-private-key-path admin.key `
  --output user-tx.json

npm run noos -- tx submit --file user-tx.json --yes

Create A Node

Node registration is part of node membership and governance workflows. The transaction type is REGISTER_NODE, and production node identity also involves node credentials and deployment configuration.

For operator workflows, start with:

Create A Contract Principal

A contract principal exists after a contract is deployed and instantiated. The contract id is then used as principalId with principalType: "contract" in bucket access rules.

For the contract path, see:

Assign Bucket Access With A CLI Recipe

Generate an access-rule payload template:

powershell
npm run noos -- recipe init:template bucket-access-rule --output rule.json

Edit rule.json. Choose:

  • bucketId
  • principalType
  • principalId
  • permissions

Example permissions:

json
["bucket:read_metadata", "bucket:read_encrypted", "bucket:write"]

Dry-run the assignment:

powershell
npm run noos -- recipe init:assign-bucket-principal `
  --payload-file rule.json `
  --signer-public-key="<bucket-admin-public-key>" `
  --signer-private-key-path bucket-admin.key `
  --dry-run

Submit it:

powershell
npm run noos -- recipe init:assign-bucket-principal `
  --payload-file rule.json `
  --signer-public-key="<bucket-admin-public-key>" `
  --signer-private-key-path bucket-admin.key `
  --yes

The signer must have bucket:admin on the target bucket.

Assign Bucket Access With A Raw Transaction

Build the ADD_BUCKET_ACCESS_RULE transaction:

powershell
npm run noos -- tx build `
  --type ADD_BUCKET_ACCESS_RULE `
  --payload-file rule.json `
  --signer-public-key="<bucket-admin-public-key>" `
  --signer-private-key-path bucket-admin.key `
  --output rule-tx.json

Submit it:

powershell
npm run noos -- tx submit --file rule-tx.json --yes

Use UPDATE_BUCKET_ACCESS_RULE to replace an existing rule's permission list. Use REMOVE_BUCKET_ACCESS_RULE to remove an explicit rule.

Inspect Permissions

List explicit bucket access rules:

powershell
npm run noos -- observability bucket-access-rules

The Admin GUI Access Rules page provides the same operator-facing view. These views are read-only; permission changes still go through signed transactions.

Audience-first NOOSChain documentation.