Sedona

Security

Overview

The Sedona Framework's security model is based upon the following principles:

Users

Any Sedona Framework application that wishes to utilize security must include an instance of the sys::UserService containing at least one sys::User component. Each sys::User component represents a user account. User components must be direct children of the UserService. The Component.name of the User component is the username.

Authentication

Each User component stores a 20 byte cred property, which is the credentials hash of the user's password. Because credentials are a one-way hash, the password is never readable. Credentials are computed as follows:

  1. text = username + ":" + password
  2. bytes = text from step 1 encoded as UTF-8
  3. cred = SHA-1 hash of bytes in step 2

You can use the sedona.util.UserUtil to programmatically compute credentials. Or you can use the command line:

D:\sedona>sedonac sedona.util.UserUtil brian secret
User:   brian:secret
Digest: 0x[74091bc2a1f43108df56281b6a74975bab86236f]
Base64: dAkbwqH0MQjfVigbanSXW6uGI28=

Network protocols that support authentication should work as follows:

  1. Generate a random nonce to be used only one time
  2. Send the nonce to the client
  3. Client should generate its credentials from username and password
  4. Client creates digest by hashing the credentials from step 3 with the nonce
  5. Client sends digest from step 4 to server
  6. Server computes expected digest from nonce and known credentials
  7. If client's digest from step 5 matches server's digest from step 6 then client is authenticated

If a protocol doesn't support authentication, then it should define a configuration property that references a user account to use for security checking.

Groups

Components are assigned into one or more security groups. There are four security groups indicated by the least significant nibble in the Component.meta property:

Group 10x01
Group 20x02
Group 30x04
Group 40x08

Components can be in multiple groups. For example: to assign a component to groups 2 and 3, set the bottom nibble of Component.meta to 0x06. If a component is not included in any groups, then that component is not network accessible.

Slots

Every slot in a component is defined as operator level or admin level for security purposes. By default a slot is admin level. You can mark a slot operator level with the @operator facet. Use Slot.isOperator() to check a slot's level.

Permissions

There are seven security permissions defined as a bitmask:

User.oroperator read0x01
User.owoperator write0x02
User.oioperator invoke0x04
User.aradmin read0x08
User.awadmin write0x10
User.aiadmin invoke0x20
User.uauser admin0x40

Users are granted zero or more of each of these seven permissions for each user group via the User.perm property. Each group's permissions is stored in a byte:

Group 1 byte 0
Group 2 byte 1
Group 3 byte 2
Group 4 byte 3

For example to grant a user operator read and write in group 1 and full permissions in group 3:

perm = ((or|ow|oi|ar|aw|ai|ua) << 16) | ((or | ow) << 0)

Permission Grants

To compute the permissions a user has on a given component, we combine the user's configured permissions for each group the given component is a member of. Consider this example of a User's configured permissions:

Groups or ow oi ar aw ai ua
Group 1 x x - x - - -
Group 2 x - x - - - -
Group 3 x x x x x x x
Group 4 - - - - - - -

Some examples of what permissions this user would be granted:

Access Control

The previous sections explain how we compute the permissions granted to a user for a specific component. The following table defines what permissions are required for operations:

Perm Operation
or to read or subscribe to a component (1)
or to read the current value of an operator property
ow to modify the current value of an operator property
oi to invoke an operator action
ar to read the current value of an admin property (2)
aw to modify the current value of an admin property
ai to invoke an admin action
aw on parent to add a child component
aw on parent to reorder children components
aw on component to rename
aw on component to delete
ar to read or subscribe to a components links
ar/aw ar on "from" component and aw on "to" component to create link
aw on "to" component to delete a link
ua on User component to read, write, modify, delete

Sox Implementation Notes:

  1. When reading a component's children via a tree update, unreadable children components are automatically omitted in the result
  2. When performing a property update or subscribe, admin properties are not serialized when not available

Provisioning

Each user is explicitly granted permissions to read and write the files associated with provisioning:

User.provAppread/write "app.sab"0x01
User.provKitsread/write "kits.scode"0x02
User.provSvmread/write "svm.*"0x04