lice.md (10720B)
- ---
 - title: "Litepub Capability Enforcement (LiCE)"
 - ---
 - # Abstract
 - Litepub Capability Enforcement (LiCE) is an extension to the [ActivityPub protocol][ap]
 - which adds support for verifying and enforcing [object capabilities][wikipedia-ocap].
 - [ap]: https://www.w3.org/TR/activitypub
 - [wikipedia-ocap]: https://en.wikipedia.org/wiki/Object-capability_model
 - # Overview
 - LiCE provides two components that, when combined, define a security model based on the
 - concept of object capabilities:
 - * **Proof objects**: Objects which have been created by an *actor* which *controls*
 - a given resource that delegate permissions related to that resource.
 - * **Capability URIs**: Well-known or private endpoint URIs which either grant
 - implicit permissions or return a proof object that permits delegation of permission
 - to perform a given action.
 - ## Security Levels
 - LiCE implementations make use of both components in different ways, depending on the
 - configured security level:
 - * `disabled`: proof objects are neither verified nor generated upon request.
 - * `permissive`: proof objects are not verified, but will be generated upon request.
 - * `enforcing`: proof objects are verified and are also generated upon request.
 - ### Why does LiCE have configurable security levels?
 - *This section is non-normative.*
 - LiCE has a configurable security level to allow for a transitional period, with the
 - eventual goal that the entire ActivityPub network eventually adopts LiCE and defaults
 - to running in an enforcing mode. It is strongly recommended that a "flag day" be set
 - where all implementations transition to having a default security level of
 - `enforcing`.
 - # The `capabilities` Object
 - Objects that have been security labeled have a new `capabilities` object that specifies
 - what capabilities are implicitly granted or require specific permissions. Capabilities
 - with implicit grants are defined using well-known URIs, such as `as:Public`.
 - A basic object that has been labeled with a `capabilities` object looks like this:
 - ```
 - {
 - "@context": [
 - "https://www.w3.org/ns/activitystreams",
 - "https://litepub.social/litepub/lice-v0.0.1.jsonld"
 - ],
 - "capabilities": {
 - "reply": "https://example.social/caps/d4c4d96a-36d9-4df5-b9da-4b8c74e02567",
 - "like": "https://www.w3.org/ns/activitystreams#Public",
 - "announce": "https://example.social/caps/e379a28e-74ce-ed7a-928c-7c3a4b2158e4"
 - },
 - "id": "https://example.social/objects/d6cb8429-4d26-40fc-90ef-a100503afb73",
 - "type": "Note",
 - "content": "I'm really excited about the new capabilities feature!",
 - "attributedTo": "https://example.social/users/bob"
 - }
 - ```
 - In this example, `Like` activities are allowed from the public, `Announce` and
 - `Create.inReplyTo` activities require explicit authorization in the form of a
 - proof object.
 - ## Optional Specifiers
 - A `capabilities` object at the minimum is an object which contains the names of
 - capabilities but may also contain additional specifiers in the typical JSON-LD
 - way:
 - ```
 - {
 - "@context": [
 - "https://www.w3.org/ns/activitystreams",
 - "https://litepub.social/litepub/lice-v0.0.1.jsonld"
 - ],
 - "capabilities": {
 - "reply": {
 - "id": "https://www.w3.org/ns/activitystreams#Public",
 - "expires": "2019-09-15T12:00:00Z"
 - },
 - "like": "https://www.w3.org/ns/activitystreams#Public",
 - "announce": "https://www.w3.org/ns/activitystreams#Public"
 - },
 - "id": "https://example.social/objects/d6cb8429-4d26-40fc-90ef-a100503afb73",
 - "type": "Note",
 - "content": "I'm really excited about the new capabilities feature!",
 - "attributedTo": "https://example.social/users/bob"
 - }
 - ```
 - > *TODO*: document a list of possible specifiers here. The `expires` specifier
 - > is obvious, but there may be other specifiers worth examining.
 - # Proof Objects
 - When a URI is used for a capability that is not a well-known URI such as `as:Public`,
 - then it is assumed to be an *authorization endpoint*. Authorization endpoints
 - behave similarly to *inboxes* but return either a *proof object* or a rejection object
 - as a response.
 - Proof objects MUST:
 - * be publicly accessible at the URI specified in their `id`
 - * of type `Accept`
 - * reference the allowed activity by either embedding it or referencing it by `id`
 - An example proof object looks like this:
 - ```
 - {
 - "@context": [
 - "https://www.w3.org/ns/activitystreams",
 - "https://litepub.social/litepub/lice-v0.0.1.jsonld"
 - ],
 - "id": "https://example.social/proofs/fa43926a-63e5-4133-9c52-36d5fc6094fa",
 - "type": "Accept",
 - "actor": "https://example.social/users/bob",
 - "object": {
 - "id": "https://example.social/activities/12945622-9ea5-46f9-9005-41c5a2364f9c",
 - "type": "Like",
 - "object": "https://example.social/objects/d6cb8429-4d26-40fc-90ef-a100503afb73",
 - "actor": "https://example.social/users/alyssa",
 - "to": [
 - "https://example.social/users/alyssa/followers",
 - "https://example.social/users/bob"
 - ]
 - }
 - }
 - ```
 - ### Attestation of Properties in the Referent Object
 - An `attestations` object contains properties and values that must match the
 - properties and values in the referent object.
 - In the event that an `attestations` object is included, the `id` property
 - MUST NOT be present.
 - When verifying proof objects that contain an `attestations` object, the verifier
 - MUST ensure that the object being authorized against the proof has the same
 - properties as present in the proof object. In the event that the proof object's
 - child fragments and the referent object disagree, the verifier MUST fail the
 - verification.
 - An example proof object with an `attestations` object:
 - ```
 - {
 - "@context": [
 - "https://www.w3.org/ns/activitystreams",
 - "https://litepub.social/litepub/lice-v0.0.1.jsonld"
 - ],
 - "id": "https://example.social/proofs/fa43926a-63e5-4133-9c52-36d5fc6094fa",
 - "type": "Accept",
 - "actor": "https://example.social/users/bob",
 - "object": {
 - "id": "https://example.social/activities/12945622-9ea5-46f9-9005-41c5a2364f9c",
 - "type": "Like",
 - "object": "https://example.social/objects/d6cb8429-4d26-40fc-90ef-a100503afb73",
 - "actor": "https://example.social/users/alyssa",
 - "to": [
 - "https://example.social/users/alyssa/followers",
 - "https://example.social/users/bob"
 - ]
 - }
 - "attestations": {
 - "type": "Like",
 - "object": "https://example.social/objects/d6cb8429-4d26-40fc-90ef-a100503afb73",
 - "to": [
 - "https://example.social/users/alyssa/followers",
 - "https://example.social/users/bob"
 - ]
 - }
 - }
 - ```
 - ## Invocation
 - When a proof object is required in order to prove an activity is authorized, it MUST be
 - attached as the `proof` field, either by embedding the object or referencing it by URI.
 - This is known as a capability invocation.
 - An example invocation where the proof object is embedded:
 - ```
 - {
 - "@context": [
 - "https://www.w3.org/ns/activitystreams",
 - "https://litepub.social/litepub/lice-v0.0.1.jsonld"
 - ],
 - "id": "https://example.social/activities/12945622-9ea5-46f9-9005-41c5a2364f9c",
 - "type": "Like",
 - "object": "https://example.social/objects/d6cb8429-4d26-40fc-90ef-a100503afb73",
 - "actor": "https://example.social/users/alyssa",
 - "to": [
 - "https://example.social/users/alyssa/followers",
 - "https://example.social/users/bob"
 - ],
 - "proof": {
 - "id": "https://example.social/proofs/fa43926a-63e5-4133-9c52-36d5fc6094fa",
 - "type": "Accept",
 - "actor": "https://example.social/users/bob",
 - "object": {
 - "id": "https://example.social/activities/12945622-9ea5-46f9-9005-41c5a2364f9c",
 - "type": "Like",
 - "object": "https://example.social/objects/d6cb8429-4d26-40fc-90ef-a100503afb73",
 - "actor": "https://example.social/users/alyssa",
 - "to": [
 - "https://example.social/users/alyssa/followers",
 - "https://example.social/users/bob"
 - ]
 - }
 - }
 - }
 - ```
 - An example where the proof object is referenced:
 - ```
 - {
 - "@context": [
 - "https://www.w3.org/ns/activitystreams",
 - "https://litepub.social/litepub/lice-v0.0.1.jsonld"
 - ],
 - "id": "https://example.social/activities/12945622-9ea5-46f9-9005-41c5a2364f9c",
 - "type": "Like",
 - "object": "https://example.social/objects/d6cb8429-4d26-40fc-90ef-a100503afb73",
 - "actor": "https://example.social/users/alyssa",
 - "to": [
 - "https://example.social/users/alyssa/followers",
 - "https://example.social/users/bob"
 - ],
 - "proof": "https://example.social/proofs/fa43926a-63e5-4133-9c52-36d5fc6094fa"
 - }
 - ```
 - ## Verification
 - Proof objects SHOULD be verified before accepting any activity which references one.
 - The default way to do this is to fetch the proof object at the given URI and verify
 - that there is a cyclical relationship between the accepted activity and the activity
 - which references the proof.
 - An optional way of verifying a proof would be to use [Linked Data Signature][lds].
 - If it is possible to verify the proof using a cryptographic signature, then refetching
 - the proof object is not necessary. All implementations MUST support fallback to
 - fetching the proof object if a valid signature is not present.
 - [lds]: https://w3c-dvcg.github.io/ld-signatures/
 - ### Verifying Attestations
 - *This section is non-normative.*
 - Implementations MUST check that properties in the `attestations` object match
 - properties in the referent object. In most cases, this is done by doing a
 - literal comparison.
 - When comparing sets (JSON arrays), an implementation SHOULD iterate over the
 - values in the attested property and verify set membership in the referent
 - property for every value. As an optimization, an implementation MAY normalize
 - a copy of both properties and match that the sequence is identical.
 - # Security Considerations
 - *This section is non-normative.*
 - ## Recursive Object Fetching Denial of Service
 - A malicious proof object could reference itself, either directly or indirectly.
 - Implementations SHOULD limit the depth to which they fetch referenced activities and
 - proof objects. A valid activity will never have a recursive loop, so the depth limit
 - can be very low.
 - ## Proof Object/Child Object Swapping
 - A malicious server could swap the authorized object with a newer version that contains
 - content that was not authorized by the granting server.
 - Implementations SHOULD include key properties of the child object when generating a
 - proof object, such as `content`, `name`, `summary` and `attachment`.
 - ## Fake Direction Spoofing
 - A malicious server could present a proof object using a third-party domain or third-party
 - actor.
 - Implementations SHOULD verify that the proof object is created by the same actor which
 - created the content being interacted with.
 - Implementations SHOULD verify that the proof object is at the same domain as the object
 - being interacted with.