8.4 The Request
The request is the first line on the editor's standard input, and the
only one that has no type. It is one JSON object:
| Member | Type | Required | Meaning |
|---|---|---|---|
object | object | Yes | What the descriptor is the descriptor of. |
object.name | string | Yes | What the object is called where the person found it: notes.txt, not a full path, unless a path is how they know it. |
object.kind | string | Yes | What kind of thing it is, in words for the person: File, Folder, Service. |
object.container | boolean | No, false | Whether other objects inherit from it (PCDS §5.6). |
object.children | string | No, "all" | What a container holds, which is what the entries made for it are passed on to: all or containers (see Containers). Ignored unless container is true. |
object.parent | object | No | What the object is in, which its inherited entries come from (see The parent). |
object.parent.name | string | Yes, in parent | What the parent is called where the person knows it: /srv. |
object.parent.sd | string | No | The parent's descriptor, self-relative and in base64 as sd is. |
object.parts | array | No, empty | The object's parts that rules can be made for one at a time: object types (see Parts and kinds). |
object.parts[].guid | string | Yes | The object type, as a GUID in its usual text form: bf967aba-0de6-11d0-a285-00aa003049e2. |
object.parts[].name | string | Yes | What the part is called, for the person. |
object.parts[].kind | string | Yes | set, a set of properties; property; or right, an action. |
object.parts[].set | string | No | For a property, the GUID of the set it is in. |
object.kinds | array | No, empty | On a container of typed things, the kinds of thing it holds: inherited object types. |
object.kinds[].guid, .name | string | Yes | The inherited object type, and what that kind of thing is called. |
object.part_rights | array | No, empty | The rights a rule for a part can give, as rights gives the object's (see Parts and kinds). |
object.part_rights[].name, .mask | string, number | Yes | What the right is called, and its access mask. |
object.naming | object | No | How a part not listed is named (see Parts named by the person). |
object.naming.namespace | string | Yes, in naming | The UUID v5 namespace a part's object type is derived in, as a GUID in its usual text form. |
object.naming.noun | string | Yes, in naming | What one such part is called, for the person: field. |
object.naming.example | string | No | A name the person might give, to show how one is written: source.name. |
sd | string | Yes | The descriptor as it is now: a self-relative Security Descriptor (PCDS §5.1), in base64 with padding (RFC 4648 §4). |
read | array of strings | No | The components sd holds as they are on the object: some of owner, group, dacl, sacl and label (see The descriptor). Left out, every component sd has. |
rights | array | Yes | The object's rights by name, in the order a person should see them. |
rights[].name | string | Yes | What the right is called. |
rights[].mask | number | Yes | The access mask the right stands for, as an unsigned 32-bit integer. |
rights[].general | boolean | No, false | Whether it is a general right (§8.2). |
generic | object | Yes | What each generic right stands for on this kind of object (PCDS §5.3). |
generic.read, .write, .execute, .all | number | Yes | The access mask each generic right maps to. |
can | object | No | Which components the requester is able to change. |
can.dacl | boolean | No, true | Whether it can change the DACL. It is true when left out because, before this member, a requester always could. |
can.owner | boolean | No, false | Whether it can change the owner. |
can.audit | boolean | No, false | Whether it can change the SACL. |
can.label | boolean | No, false | Whether it can apply the label by itself (§8.5). |
can.propagate | boolean | No, false | Whether, on a container, it can push what was applied into what is already inside (§8.5, Pushing into what is inside). |
can.why | string | No | Why the requester cannot change what can says it cannot, as text for the person. |
8.4.1 The descriptor #
The requester SHOULD include the owner, the group and the DACL. It MAY
leave out the SACL: reading a SACL takes ACCESS_SYSTEM_SECURITY, which
a requester need not have. It SHOULD include the label where it can
read it, which takes only READ_CONTROL. A requester that could read the
label and not the rest of the SACL sends a SACL holding the label
alone, and MUST then say so in read, naming label and not sacl.
The editor MUST NOT take a SACL for the whole SACL unless read names
sacl or is left out. Where it is only the label, the editor MUST NOT
show it as an object with no auditing, claims or policies, since those
are not known.
A descriptor with no DACL component means one with no access list, which PCDS §5.1 treats as granting everyone everything. The editor MUST show it as such and not as an empty list, which grants nobody anything.
8.4.2 The parent #
object.parent names what the object's inherited entries come from,
for the person: "Inherited from /srv". An editor that offers to stop
inheriting MAY offer to inherit again, but KACS does not pass a
parent's entries down again by itself when protection is turned off
(PCDS §5.6): the editor works out what is passed down from
object.parent.sd, and SHOULD NOT offer to inherit again without it.
A requester SHOULD send the parent's descriptor where it can read it.
8.4.3 Parts and kinds #
object.parts lists the object types (PCDS §5.4) a rule can be made
for, as an account's sign-in details or the action of resetting its
password. object.kinds lists, for a container of typed things, the
kinds of thing it holds, which an entry can be passed on to alone. An
editor MAY offer rules for parts and kinds only where they are listed,
and MUST keep as it found it an entry naming a GUID it is not told of.
object.part_rights names what a rule for a part can give. Left out,
an editor offers what a directory's parts take: reading and writing a
property, and using an action. A requester whose parts take other rights
MUST send them. eventd's fields, for example, take only its Read.
8.4.3.1 Parts named by the person #
Some objects have more parts than can be listed, each one's object type
derived from its name. eventd's fields are an example: a payload field
needs no registration, and its GUID is derived from its name (eventd TRM
§7.3). object.naming tells the editor how such a part is named. Its
object type is the UUID v5 (RFC 9562 §5.5) of the name, as UTF-8, in
naming.namespace, and it is a property.
An editor MAY then let the person name a part beside those listed. It
MUST derive the object type exactly so, and SHOULD show the part by the
name given for as long as the dialog is open. A requester SHOULD still
list in parts the ones it knows, so that an existing rule for one is
shown by name.
8.4.4 The rights #
rights names every right the requester wants a person to see.
General rights SHOULD come first, from the one granting the most to the
one granting the least, so that a right that includes another is above
it. The masks of two rights MAY overlap, and typically do: "Modify"
includes "Read".
An editor that shows general rights as boxes to tick SHOULD show as a whole what a mask it cannot express in them — a mask with bits outside every general right it contains, an entry of a type it does not edit, or inheritance flags other than its own — rather than leave it unshown, and SHOULD keep such an entry as it found it.
generic lets the editor read an entry that grants generic rights
(PCDS §5.3) as the rights they stand for. The requester MUST give the
mapping its kind of object actually uses.
8.4.5 Containers #
On a container, the entries an editor makes apply to the container and
are passed on to what it holds. object.children says what that is,
and so which inheritance flags (PCDS §5.6) those entries carry:
| Value | Holds | Flags of an entry made here |
|---|---|---|
all | Containers and other objects, as a folder holds folders and files. | Object inherit and container inherit. |
containers | Containers alone, as a registry key holds keys and nothing else. | Container inherit. |
An entry with other inheritance flags is one the editor cannot express in its general rights (above), and is shown as a whole and kept.
8.4.6 What the requester can change #
can says what the requester is able to change. It MUST NOT say it
can change a component it cannot. can.label is true only where it can
apply the label by itself, which takes WRITE_OWNER and, for a level
above the caller's own, SeRelabelPrivilege (KACS set-security). It SHOULD find out by asking the
system, for example by an AccessCheck of the person's token against the
descriptor, or by opening the object for the rights that changing it
takes. It SHOULD NOT infer it from the person's group memberships.
can.propagate is true only on a container whose requester holds what
is inside it and can walk it: a file explorer for a folder, a registry
editor for a key. It says nothing about whether each item inside can be
changed, which is found out item by item as the walk goes (§8.5).
A requester that cannot change the DACL still sends it, so that the
person can read it. The editor MUST then show the DACL without offering
to change it, and SHOULD say why, with can.why if it was given. An
editor whose requester can change nothing SHOULD offer only to close.
8.4.7 Validation #
An editor that cannot use the request — one that is not a JSON object,
lacks a required member, or carries an sd that is not a Security
Descriptor — MUST NOT show a dialog. It SHOULD write why to its
standard error, and MUST end (§8.3).