Every one needs to protect secret information from being accessed, and CYFS is an open platform, and anyone has the opportunity to read the information stored on it. The best way to protect privacy is not to deal with other people, and sensitive information is not shown to others. In CYFS, it is necessary to protect the ObjectId of sensitive information. Once someone else gets your ObjectId, it is possible to get the object content itself. This is very important, and it should be regarded as a principle for using CYFS. Information can be leaked in many ways:
Send to others actively.
Malicious or poor quality DECApps may deliver it on purpose or accidentally. Therefore, We should try our best to install DECApp from a reliable source, and even read the source code and build DECApp by ourselves.
It's too difficult to distinguish and prevent dangerous behaviors by users themselves. Therefore, CYFS provides a permission system to help users manage private data. The user can prohibit all DECApp except the system DECApp from accessing an object, and can also prohibit any other user from actively accessing an object. No one can read the object content without permissions even if the ObjectId is leaked. As a basic system, CYFS provides a flexible methods to config the permissions, which can only open partial access permissions for specific trusted users or DECApp; of course, the author cannot prevent Object from continuing to propagate after it has been displayed to others, It's also unpreventable in real world.
Let me emphasize again that users should try their best to abide by the confidentiality principle mentioned above. The system can only provide auxiliary management capabilities and cannot be used as the final guarantee.
I will describe the design of the CYFS permissions (hereafter referred to as ACL) system as follow.
Default Permissions
If no permissions are configured for an Object, the default permissions are effective as follows:
If the Owner of Object is not itself, anyone has the full permissions.
If the request is from the current Zone or a friend Zone, and the source DECApp is same as the DECApp that constructs Object, the request will be granted.
It's important to add friends cautiously!
Otherwise the request will be prevented.
Level
Currently, CYFS already supports several ways to configure ACL:
Configured by the req_path field of the request:
It can be used to prevent the requests to the service provided by DECApp.
It can be used to restrict the access rights of the RootState subtree, and its lower-level subtrees also apply the same permission configuration, unless the lower-level subtrees are configured otherwise.
Configure objects that meet certain rules (rmeta).
Configure for a single object.
The rules are hit one by one in above order, and the permission configuration with the highest matching degree is found and applied. If you still remember the architectural design of CyfsStack, the ACL system is a Processor in it, and the implementation code is in src\cyfs-stack\src\non_api\acl.
Static configuration as file
ACL can be statically configured by app-manager to read the acl configuration in the installation package when DECApp is installed. For the specific configuration method, refer to the app_acl_config field of the cyfs.config.json file.
The file is used to configure the permissions that the app needs and awarded to others by the app. This file will be read by app-manager when the app is installed, and the corresponding permissions will be registered with the system according to the configured values.
A complete permission configuration file is shown as follows:
[self]
[self.access] // Grant permissions to your own data by path
// /test3 by each alone group
"/test3" = [{group = "OthersDec", access = "-wx"}, {group = "CurrentDevice", access = "---"}]
// complete string, set/clear each bits for each group
"/test2" = "rwxrwxrwx---rwx---"
"/test1" = "rwxrwxrwx---rwx--x"
[self.specified] // Authorize your own data to the specified DECApp or user
"/test3" = {access = "--x", dec_id = "9tGpLNnDpa8deXEk2NaWGccEu4yFQ2DrTZJPLYLTxxxx"} // The specified DECApp running on any zone can call the specified path.
"/test2" = {access = "--x", zone_category = "current-zone", dec_id = "9tGpLNnDpa8deXEk2NaWGccEu4yFQ2DrTZJPLYLTxxxx"} // The specified DECApp running on the specified zone can call the specified path.
"/test1" = {access = "--x", zone = "5aSixgLwnWbmcDKwBtTBd7p9U4bmqwNU2C6h6SCvxxxx"} // Any DECApp running on the specified zone can call the specified path.
// Request authorization from a specified DECApp(DECID_A)
[DECID_A.specified]
// The `dec_id` field in SpecifiedGroup will never be set, otherwise the rule will be discarded.
"/test3" = {access = "--x"} // Apply for the permission to call the specified path.
"/test2" = {access = "--x", zone_category = "current-zone"} // Apply for the permission to call the specified path limited in the specified zone("current-zone").
"/test1" = {access = "--x", zone = "5aSixgLwnWbmcDKwBtTBd7p9U4bmqwNU2C6h6SCvxxxx"} // Apply for the permission to call the specified path limited in the specified zone("5aSixgLwnWbmcDKwBtTBd7p9U4bmqwNU2C6h6SCvxxxx").
[DECID_A.config] // **None currently?**
This file is structured in toml format, where each section represents authorization in the same direction, and the section name rules are as follows:
${dec_id}: the DecAppId that needs to provide permissions. If it is the current DecAppId (can be replaced by self), it means that the permission is open to others, otherwise, it means that the current DECApp needs the permissions from the specified DECApp.
access: A more general permission configuration method divided by group,
specified: The way to configure permissions for specific targets (DECApp, Zone, etc.), key is the request path, which can be the path of RootState, or the value of req_path in the request. It can manage permissions more granularly than access
${key}: request path, which can be the path of RootState, or the value of req_path in the request.
AccessString: Indicates the complete permission corresponding to a path. Refer to the file system permission in linux. A set of specific permissions is represented by 3 bits. A total of 6 groups of 18 bits represent a complete permission, and each bit represents the authorization of the corresponding group.
There are 3 permissions currently: Read/Write/Call:
Now, there are 2 methods to represent an AccessString in a configuration file:
A complete string, use an 18-chats string to represent a complete permission, and use linux "rwx-" in the group to represent the permission of each bit. Groups can be separated by spaces or underscores
Example: Full permissions for OwnerDec in CurrentDevice | CurrentZone, read | write permissions for OwnerDec in FriendZone, and read permission for OthersDec in OthersZone. We can express it as "rwxrwxrw-r--rwxr--"; it is equivalent to "rwx rwx rw- r-- rwx r--" or "rwx_rwx_rw-_r--_rwx_r--".
Grant permissions for specified groups separately based on the default permissions, expressed as an array formed as {group, access}, group is the enumeration name of AccessGroup, and access is a 3-chats "rwx-" string.
Still take the above permissions as an example, expressed as [{group = "FriendZone", access = "rw-"}, {group = "OthersZone", access = "r--"}, {group = "OthersDec" , access = "r--"}]
SpecifiedGroup: The permissions of a specific DECApp, Zone, or zone_category, the difference from AccessString is that AccessString can only configure permissions for each group, and SpecifiedGroup can limit permissions into a specific DECApp or Zone.
There are 4 fields:
access: Permission configuration, which is a 3-chats "rwx-" string
zone: ZoneId of the Zone which the permission is applied to. Here, it is usually filled with the PeopleId of Zone. You can also fill in a DeviceId, indicating that it is limited to a specific Device. We can remove the field to match any device.
zone_category: The group of zone this permission will be applied to, if not filled, it means for any devices. Can take one of the following values:
"current-device"
"current-zone"
"friend-zone"
"other-zone"
I found that the zone_category is words with hyphen, it's different with it in AccessGroup for AccessString. can we use the same style?
dec_id: DECApp which this permission applies to, if not filled, it means for any DECApps.
Among the 4 fields, access is required, and zone, zone_category, and dec_id must be filled in at least one. The permission will be passed when all the three conditions of zone, zone_category, and dec_id are matched.
Dynamic configuration interface
We can config the ACL statically by app-manager to read the acl configuration in the installation package when DECApp is installed. And we can also config it dynamically by calling SharedCyfsStack when the DECApp is running. The entry point of the dynamic configuration interface is:
let meta: GlobalStateMetaStub = SharedCyfsStack.root_state_meta_stub();
GlobalStateMetaStub provides different interfaces for various configuration methods. I will introduce as follow.
req_path constraints
add_access: Add a permission constraint on req_path, the core structure is designed as follows:
pub struct GlobalStatePathAccessItem {
// GlobalState path, must end with /
pub path: String,
// Access value, it's a `AccessString` as uint32, or a SpecifiedGroup
pub access: GlobalStatePathGroupAccess,
}
remove_access: Use path as key to delete the parameter specified permission.
rmeta constraints
add_object_meta: Add a matching rule, the core structure is designed as follows:
remove_object_meta: Use selector as key, delete the permission specified by the parameter.
object_id constraints
Just specify the access parameter directly when put_object is called, if you want to change it, call put_object again.
Principles of select
How to choose a method to config the permission, I suggest as follow:
You should write it clearly in the static configuration file if you want to grant permissions to the others (other DECApp or Zone); dynamic configuration in the program is more difficult to maintain. You can use dynamic configuration if the static configuration file can not do it.
You must write it in this configuration file and let app-manager register during installation, if you want to request permissions from other DECApp. There is no way to register dynamically in code.
You must use the specified section to request permissions from other DECApp, anything in the access field is ignored.
There is no way to request permissions from other zone.
CYFS permission system
Every one needs to protect secret information from being accessed, and
CYFS
is an open platform, and anyone has the opportunity to read the information stored on it. The best way to protect privacy is not to deal with other people, and sensitive information is not shown to others. InCYFS
, it is necessary to protect theObjectId
of sensitive information. Once someone else gets yourObjectId
, it is possible to get the object content itself. This is very important, and it should be regarded as a principle for usingCYFS
. Information can be leaked in many ways:DECApp
s may deliver it on purpose or accidentally. Therefore, We should try our best to installDECApp
from a reliable source, and even read the source code and buildDECApp
by ourselves.It's too difficult to distinguish and prevent dangerous behaviors by users themselves. Therefore,
CYFS
provides a permission system to help users manage private data. The user can prohibit allDECApp
except the systemDECApp
from accessing an object, and can also prohibit any other user from actively accessing an object. No one can read the object content without permissions even if theObjectId
is leaked. As a basic system,CYFS
provides a flexible methods to config the permissions, which can only open partial access permissions for specific trusted users orDECApp
; of course, the author cannot preventObject
from continuing to propagate after it has been displayed to others, It's also unpreventable in real world.Let me emphasize again that users should try their best to abide by the confidentiality principle mentioned above. The system can only provide auxiliary management capabilities and cannot be used as the final guarantee.
I will describe the design of the
CYFS
permissions (hereafter referred to asACL
) system as follow.Default Permissions
If no permissions are configured for an
Object
, the default permissions are effective as follows:If the
Owner
ofObject
is not itself, anyone has the full permissions.If the request is from the current
Zone
or a friendZone
, and the sourceDECApp
is same as theDECApp
that constructsObject
, the request will be granted.It's important to add friends cautiously!
Otherwise the request will be prevented.
Level
Currently,
CYFS
already supports several ways to configureACL
:req_path
field of the request:DECApp
.RootState
subtree, and its lower-level subtrees also apply the same permission configuration, unless the lower-level subtrees are configured otherwise.rmeta
).The rules are hit one by one in above order, and the permission configuration with the highest matching degree is found and applied. If you still remember the architectural design of
CyfsStack
, theACL
system is aProcessor
in it, and the implementation code is insrc\cyfs-stack\src\non_api\acl
.Static configuration as file
ACL
can be statically configured byapp-manager
to read theacl
configuration in the installation package whenDECApp
is installed. For the specific configuration method, refer to theapp_acl_config
field of thecyfs.config.json
file.The file is used to configure the permissions that the app needs and awarded to others by the app. This file will be read by
app-manager
when the app is installed, and the corresponding permissions will be registered with the system according to the configured values.A complete permission configuration file is shown as follows:
This file is structured in
toml
format, where each section represents authorization in the same direction, and the section name rules are as follows:${SectionName} = ${dec_id}[.access|specified|config]
DecAppId
that needs to provide permissions. If it is the currentDecAppId
(can be replaced byself
), it means that the permission is open to others, otherwise, it means that the currentDECApp
needs the permissions from the specifiedDECApp
.DECApp
,Zone
, etc.),key
is the request path, which can be the path ofRootState
, or the value ofreq_path
in the request. It can manage permissions more granularly thanaccess
The content of each line is as follows:
${SectionRow} = ${key} = ${AccessString} | ${SpecifiedGroup}
${key}: request path, which can be the path of
RootState
, or the value ofreq_path
in the request.AccessString
: Indicates the complete permission corresponding to a path. Refer to the file system permission in linux. A set of specific permissions is represented by 3 bits. A total of 6 groups of 18 bits represent a complete permission, and each bit represents the authorization of the corresponding group.There are 3 permissions currently: Read/Write/Call:
And there are 6 groups divided according to device and
DECApp
:Now, there are 2 methods to represent an
AccessString
in a configuration file:{group, access}
,group
is the enumeration name ofAccessGroup
, andaccess
is a 3-chats "rwx-" string.SpecifiedGroup
: The permissions of a specificDECApp
,Zone
, orzone_category
, the difference fromAccessString
is thatAccessString
can only configure permissions for each group, andSpecifiedGroup
can limit permissions into a specificDECApp
orZone
.There are 4 fields:
access
: Permission configuration, which is a 3-chats "rwx-" stringzone
:ZoneId
of theZone
which the permission is applied to. Here, it is usually filled with thePeopleId
ofZone
. You can also fill in aDeviceId
, indicating that it is limited to a specificDevice
. We can remove the field to match any device.zone_category
: The group ofzone
this permission will be applied to, if not filled, it means for any devices. Can take one of the following values:I found that the zone_category is
words with hyphen
, it's different with it inAccessGroup
forAccessString
. can we use the same style?dec_id
:DECApp
which this permission applies to, if not filled, it means for anyDECApp
s.Among the 4 fields,
access
is required, andzone
,zone_category
, anddec_id
must be filled in at least one. The permission will be passed when all the three conditions ofzone
,zone_category
, anddec_id
are matched.Dynamic configuration interface
We can config the
ACL
statically byapp-manager
to read theacl
configuration in the installation package whenDECApp
is installed. And we can also config it dynamically by callingSharedCyfsStack
when theDECApp
is running. The entry point of the dynamic configuration interface is:GlobalStateMetaStub
provides different interfaces for various configuration methods. I will introduce as follow.req_path
constraintsreq_path
, the core structure is designed as follows:path
askey
to delete the parameter specified permission.rmeta
constraintsWe can use the following operators in
selector
:The
key
and correspondingvalue
are as follows:selector
askey
, delete the permission specified by the parameter.object_id
constraintsaccess
parameter directly whenput_object
is called, if you want to change it, callput_object
again.Principles of select
How to choose a method to config the permission, I suggest as follow:
You should write it clearly in the static configuration file if you want to grant permissions to the others (other
DECApp
orZone
); dynamic configuration in the program is more difficult to maintain. You can usedynamic configuration
if the static configuration file can not do it.You must write it in this configuration file and let
app-manager
register during installation, if you want to request permissions from otherDECApp
. There is no way to register dynamically in code.You must use the
specified
section to request permissions from otherDECApp
, anything in theaccess
field is ignored.There is no way to request permissions from other
zone
.