@kybernesis/arp-scope-catalog 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (61) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +80 -0
  3. package/dist/index.cjs +518 -0
  4. package/dist/index.cjs.map +1 -0
  5. package/dist/index.d.cts +144 -0
  6. package/dist/index.d.ts +144 -0
  7. package/dist/index.js +501 -0
  8. package/dist/index.js.map +1 -0
  9. package/generated/manifest.json +1542 -0
  10. package/generated/scopes.json +1536 -0
  11. package/package.json +49 -0
  12. package/scopes/calendar.availability.read.yaml +35 -0
  13. package/scopes/calendar.events.cancel.yaml +24 -0
  14. package/scopes/calendar.events.create.yaml +31 -0
  15. package/scopes/calendar.events.modify.yaml +24 -0
  16. package/scopes/calendar.events.propose.yaml +35 -0
  17. package/scopes/calendar.events.read.yaml +38 -0
  18. package/scopes/connection.extend.yaml +28 -0
  19. package/scopes/connection.rescope.request.yaml +21 -0
  20. package/scopes/contacts.attributes.read.yaml +25 -0
  21. package/scopes/contacts.introduce.yaml +21 -0
  22. package/scopes/contacts.search.yaml +26 -0
  23. package/scopes/contacts.share.yaml +30 -0
  24. package/scopes/credentials.present.request.yaml +29 -0
  25. package/scopes/credentials.proof.zk.request.yaml +31 -0
  26. package/scopes/delegation.forward.task.yaml +36 -0
  27. package/scopes/files.project.files.delete.yaml +31 -0
  28. package/scopes/files.project.files.list.yaml +22 -0
  29. package/scopes/files.project.files.read.yaml +35 -0
  30. package/scopes/files.project.files.summarize.yaml +30 -0
  31. package/scopes/files.project.files.write.yaml +34 -0
  32. package/scopes/files.project.metadata.read.yaml +21 -0
  33. package/scopes/files.projects.list.yaml +18 -0
  34. package/scopes/files.share.external.yaml +39 -0
  35. package/scopes/identity.card.read.yaml +18 -0
  36. package/scopes/identity.introduction.request.yaml +24 -0
  37. package/scopes/identity.principal.verify.yaml +19 -0
  38. package/scopes/knowledge.query.yaml +31 -0
  39. package/scopes/messaging.chat.send.yaml +27 -0
  40. package/scopes/messaging.email.draft.compose.yaml +23 -0
  41. package/scopes/messaging.email.send.reviewed.yaml +36 -0
  42. package/scopes/messaging.email.summary.yaml +26 -0
  43. package/scopes/messaging.email.thread.read.yaml +29 -0
  44. package/scopes/messaging.relay.to_principal.yaml +22 -0
  45. package/scopes/notes.read.yaml +25 -0
  46. package/scopes/notes.search.yaml +24 -0
  47. package/scopes/notes.write.yaml +32 -0
  48. package/scopes/payments.authorize.capped.yaml +37 -0
  49. package/scopes/payments.history.read.yaml +28 -0
  50. package/scopes/payments.quote.request.yaml +18 -0
  51. package/scopes/payments.refund.request.yaml +24 -0
  52. package/scopes/tasks.assign.yaml +27 -0
  53. package/scopes/tasks.create.yaml +31 -0
  54. package/scopes/tasks.list.yaml +21 -0
  55. package/scopes/tasks.read.yaml +22 -0
  56. package/scopes/tasks.status.update.yaml +22 -0
  57. package/scopes/tools.invoke.mutating.yaml +37 -0
  58. package/scopes/tools.invoke.read.yaml +28 -0
  59. package/scopes/work.projects.list.yaml +18 -0
  60. package/scopes/work.reports.summary.yaml +29 -0
  61. package/scopes/work.status.read.yaml +18 -0
package/package.json ADDED
@@ -0,0 +1,49 @@
1
+ {
2
+ "name": "@kybernesis/arp-scope-catalog",
3
+ "version": "0.2.0",
4
+ "description": "ARP scope catalog v1 — 50 scope templates + Handlebars→Cedar compiler.",
5
+ "license": "MIT",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "https://github.com/KybernesisAI/arp.git",
9
+ "directory": "packages/scope-catalog"
10
+ },
11
+ "publishConfig": {
12
+ "access": "public"
13
+ },
14
+ "type": "module",
15
+ "main": "./dist/index.cjs",
16
+ "module": "./dist/index.js",
17
+ "types": "./dist/index.d.ts",
18
+ "exports": {
19
+ ".": {
20
+ "types": "./dist/index.d.ts",
21
+ "import": "./dist/index.js",
22
+ "require": "./dist/index.cjs"
23
+ },
24
+ "./scopes/*": "./scopes/*.yaml",
25
+ "./generated/manifest.json": "./generated/manifest.json",
26
+ "./generated/scopes.json": "./generated/scopes.json"
27
+ },
28
+ "files": [
29
+ "dist",
30
+ "scopes",
31
+ "generated",
32
+ "README.md"
33
+ ],
34
+ "dependencies": {
35
+ "handlebars": "^4.7.8",
36
+ "yaml": "^2.6.0",
37
+ "zod": "^3.23.8",
38
+ "@kybernesis/arp-spec": "0.2.0"
39
+ },
40
+ "devDependencies": {
41
+ "@cedar-policy/cedar-wasm": "^3.2.4"
42
+ },
43
+ "scripts": {
44
+ "build": "tsup && node ./scripts/build-catalog.mjs",
45
+ "test": "vitest run",
46
+ "typecheck": "tsc --noEmit",
47
+ "lint": "eslint src tests"
48
+ }
49
+ }
@@ -0,0 +1,35 @@
1
+ id: calendar.availability.read
2
+ version: 1.0.0
3
+ label: Check availability (free/busy only)
4
+ description: Peer can see when you're free or busy, but no event titles, attendees, or details.
5
+ category: calendar
6
+ risk: low
7
+ parameters:
8
+ - name: days_ahead
9
+ type: Integer
10
+ required: true
11
+ default: 14
12
+ validation: "1..90"
13
+ cedar_template: |
14
+ permit (
15
+ principal == Agent::"{{audience_did}}",
16
+ action == Action::"check_availability",
17
+ resource == Calendar::"primary"
18
+ ) when {
19
+ context.query_window_days <= {{days_ahead}}
20
+ };
21
+ forbid (
22
+ principal == Agent::"{{audience_did}}",
23
+ action,
24
+ resource == Calendar::"primary"
25
+ ) when {
26
+ action != Action::"check_availability"
27
+ };
28
+ consent_text_template: "Check your free/busy (no details) up to {{days_ahead}} days ahead."
29
+ obligations_forced:
30
+ - type: redact_fields
31
+ params:
32
+ fields: ["event.title", "event.attendees", "event.description", "event.location"]
33
+ implies: []
34
+ conflicts_with: []
35
+ step_up_required: false
@@ -0,0 +1,24 @@
1
+ id: calendar.events.cancel
2
+ version: 1.0.0
3
+ label: Cancel events
4
+ description: Peer can cancel calendar events on your behalf.
5
+ category: calendar
6
+ risk: high
7
+ parameters: []
8
+ cedar_template: |
9
+ permit (
10
+ principal == Agent::"{{audience_did}}",
11
+ action == Action::"cancel_event",
12
+ resource == Calendar::"primary"
13
+ );
14
+ consent_text_template: "Cancel calendar events on your behalf."
15
+ obligations_forced:
16
+ - type: audit_level
17
+ params:
18
+ level: verbose
19
+ - type: notify_principal
20
+ params: {}
21
+ implies:
22
+ - calendar.events.read
23
+ conflicts_with: []
24
+ step_up_required: true
@@ -0,0 +1,31 @@
1
+ id: calendar.events.create
2
+ version: 1.0.0
3
+ label: Create events directly
4
+ description: Peer can create calendar events on your primary calendar without extra confirmation, up to a daily cap.
5
+ category: calendar
6
+ risk: high
7
+ parameters:
8
+ - name: max_per_day
9
+ type: Integer
10
+ required: true
11
+ default: 5
12
+ validation: "1..50"
13
+ cedar_template: |
14
+ permit (
15
+ principal == Agent::"{{audience_did}}",
16
+ action == Action::"create_event",
17
+ resource == Calendar::"primary"
18
+ ) when {
19
+ context.events_created_today < {{max_per_day}}
20
+ };
21
+ consent_text_template: "Create calendar events directly, up to {{max_per_day}} per day."
22
+ obligations_forced:
23
+ - type: audit_level
24
+ params:
25
+ level: verbose
26
+ - type: notify_principal
27
+ params: {}
28
+ implies:
29
+ - calendar.availability.read
30
+ conflicts_with: []
31
+ step_up_required: true
@@ -0,0 +1,24 @@
1
+ id: calendar.events.modify
2
+ version: 1.0.0
3
+ label: Modify existing events
4
+ description: Peer can modify existing calendar events (reschedule, update details).
5
+ category: calendar
6
+ risk: high
7
+ parameters: []
8
+ cedar_template: |
9
+ permit (
10
+ principal == Agent::"{{audience_did}}",
11
+ action == Action::"modify_event",
12
+ resource == Calendar::"primary"
13
+ );
14
+ consent_text_template: "Modify existing calendar events on your behalf."
15
+ obligations_forced:
16
+ - type: audit_level
17
+ params:
18
+ level: verbose
19
+ - type: notify_principal
20
+ params: {}
21
+ implies:
22
+ - calendar.events.read
23
+ conflicts_with: []
24
+ step_up_required: true
@@ -0,0 +1,35 @@
1
+ id: calendar.events.propose
2
+ version: 1.0.0
3
+ label: Propose a meeting
4
+ description: Peer can propose a meeting. Creates a tentative event pending your confirmation.
5
+ category: calendar
6
+ risk: medium
7
+ parameters:
8
+ - name: max_attendees
9
+ type: Integer
10
+ required: true
11
+ default: 10
12
+ validation: "1..50"
13
+ - name: max_duration_min
14
+ type: Integer
15
+ required: true
16
+ default: 60
17
+ validation: "15..480"
18
+ cedar_template: |
19
+ permit (
20
+ principal == Agent::"{{audience_did}}",
21
+ action == Action::"propose_meeting",
22
+ resource == Calendar::"primary"
23
+ ) when {
24
+ context.proposed_attendee_count <= {{max_attendees}} &&
25
+ context.proposed_duration_min <= {{max_duration_min}}
26
+ };
27
+ consent_text_template: "Propose meetings (up to {{max_attendees}} people, {{max_duration_min}} minutes). You confirm before it's booked."
28
+ obligations_forced:
29
+ - type: require_principal_confirmation
30
+ params:
31
+ max_age_seconds: 86400
32
+ implies:
33
+ - calendar.availability.read
34
+ conflicts_with: []
35
+ step_up_required: false
@@ -0,0 +1,38 @@
1
+ id: calendar.events.read
2
+ version: 1.0.0
3
+ label: Read event details
4
+ description: Peer can read the details of calendar events within a time window.
5
+ category: calendar
6
+ risk: medium
7
+ parameters:
8
+ - name: window_days
9
+ type: Integer
10
+ required: true
11
+ default: 30
12
+ validation: "1..365"
13
+ - name: include_private
14
+ type: Enum
15
+ required: false
16
+ default: "no"
17
+ validation: ["yes", "no"]
18
+ cedar_template: |
19
+ permit (
20
+ principal == Agent::"{{audience_did}}",
21
+ action == Action::"read",
22
+ resource == Calendar::"primary"
23
+ ) when {
24
+ context.query_window_days <= {{window_days}}
25
+ {{#if include_private_flag}}
26
+ {{else}}
27
+ && !resource.tags.contains("private")
28
+ {{/if}}
29
+ };
30
+ consent_text_template: "Read event details for the next {{window_days}} days."
31
+ obligations_forced:
32
+ - type: audit_level
33
+ params:
34
+ level: verbose
35
+ implies:
36
+ - calendar.availability.read
37
+ conflicts_with: []
38
+ step_up_required: false
@@ -0,0 +1,28 @@
1
+ id: connection.extend
2
+ version: 1.0.0
3
+ label: Extend connection expiry
4
+ description: Peer can request that you extend this connection's expiry by a bounded number of days.
5
+ category: identity
6
+ risk: medium
7
+ parameters:
8
+ - name: days
9
+ type: Integer
10
+ required: true
11
+ default: 30
12
+ validation: "1..365"
13
+ cedar_template: |
14
+ permit (
15
+ principal == Agent::"{{audience_did}}",
16
+ action == Action::"extend_connection",
17
+ resource == Connection::"self"
18
+ ) when {
19
+ context.requested_extension_days <= {{days}}
20
+ };
21
+ consent_text_template: "Allow Peer to request a connection extension up to {{days}} days."
22
+ obligations_forced:
23
+ - type: require_principal_confirmation
24
+ params:
25
+ max_age_seconds: 0
26
+ implies: []
27
+ conflicts_with: []
28
+ step_up_required: false
@@ -0,0 +1,21 @@
1
+ id: connection.rescope.request
2
+ version: 1.0.0
3
+ label: Request new scopes
4
+ description: Peer can ask you to add or adjust scopes on this connection (subject to your approval).
5
+ category: identity
6
+ risk: medium
7
+ parameters: []
8
+ cedar_template: |
9
+ permit (
10
+ principal == Agent::"{{audience_did}}",
11
+ action == Action::"request_rescope",
12
+ resource == Connection::"self"
13
+ );
14
+ consent_text_template: "Allow Peer to propose new scopes on this connection."
15
+ obligations_forced:
16
+ - type: require_principal_confirmation
17
+ params:
18
+ max_age_seconds: 0
19
+ implies: []
20
+ conflicts_with: []
21
+ step_up_required: false
@@ -0,0 +1,25 @@
1
+ id: contacts.attributes.read
2
+ version: 1.0.0
3
+ label: Read specific contact attributes
4
+ description: Peer can read specific attribute fields (e.g., phone, title) on contacts you've identified.
5
+ category: contacts
6
+ risk: medium
7
+ parameters:
8
+ - name: attributes
9
+ type: AttributeList
10
+ required: true
11
+ validation: ["name", "email", "phone", "title", "company", "linkedin", "twitter", "notes"]
12
+ cedar_template: |
13
+ permit (
14
+ principal == Agent::"{{audience_did}}",
15
+ action == Action::"read",
16
+ resource == Contact
17
+ );
18
+ consent_text_template: "Read these contact attributes: {{attributes_display}}."
19
+ obligations_forced:
20
+ - type: redact_fields_except
21
+ params:
22
+ allowlist: "{{attributes_json}}"
23
+ implies: []
24
+ conflicts_with: []
25
+ step_up_required: false
@@ -0,0 +1,21 @@
1
+ id: contacts.introduce
2
+ version: 1.0.0
3
+ label: Request contact introduction
4
+ description: Peer can ask you to introduce them to one of your contacts.
5
+ category: contacts
6
+ risk: medium
7
+ parameters: []
8
+ cedar_template: |
9
+ permit (
10
+ principal == Agent::"{{audience_did}}",
11
+ action == Action::"request_contact_introduction",
12
+ resource == Contact
13
+ );
14
+ consent_text_template: "Let Peer ask you for introductions to your contacts."
15
+ obligations_forced:
16
+ - type: require_principal_confirmation
17
+ params:
18
+ max_age_seconds: 86400
19
+ implies: []
20
+ conflicts_with: []
21
+ step_up_required: false
@@ -0,0 +1,26 @@
1
+ id: contacts.search
2
+ version: 1.0.0
3
+ label: Look up contacts
4
+ description: Peer can search your contacts and receive only the attributes you specify.
5
+ category: contacts
6
+ risk: medium
7
+ parameters:
8
+ - name: attribute_allowlist
9
+ type: AttributeList
10
+ required: true
11
+ default: ["name", "email"]
12
+ validation: ["name", "email", "phone", "title", "company", "linkedin", "twitter", "notes"]
13
+ cedar_template: |
14
+ permit (
15
+ principal == Agent::"{{audience_did}}",
16
+ action == Action::"search_contacts",
17
+ resource == Contact
18
+ );
19
+ consent_text_template: "Search your contacts and see these fields: {{attribute_allowlist_display}}."
20
+ obligations_forced:
21
+ - type: redact_fields_except
22
+ params:
23
+ allowlist: "{{attribute_allowlist_json}}"
24
+ implies: []
25
+ conflicts_with: []
26
+ step_up_required: false
@@ -0,0 +1,30 @@
1
+ id: contacts.share
2
+ version: 1.0.0
3
+ label: Share a contact card
4
+ description: Peer can ask you to share a contact's vCard to an allowlisted recipient.
5
+ category: contacts
6
+ risk: high
7
+ parameters:
8
+ - name: recipient_allowlist
9
+ type: EmailList
10
+ required: true
11
+ validation: "rfc5322-or-domain-glob"
12
+ cedar_template: |
13
+ permit (
14
+ principal == Agent::"{{audience_did}}",
15
+ action == Action::"share_external",
16
+ resource == Contact
17
+ ) when {
18
+ context.recipient_matches_allowlist({{recipient_allowlist_json}})
19
+ };
20
+ consent_text_template: "Share contact cards externally to: {{recipient_allowlist_display}}."
21
+ obligations_forced:
22
+ - type: require_principal_confirmation
23
+ params:
24
+ max_age_seconds: 0
25
+ - type: audit_level
26
+ params:
27
+ level: verbose
28
+ implies: []
29
+ conflicts_with: []
30
+ step_up_required: true
@@ -0,0 +1,29 @@
1
+ id: credentials.present.request
2
+ version: 1.0.0
3
+ label: Request specific VCs
4
+ description: Peer can ask your agent to present specific Verifiable Credentials (full disclosure, not ZK).
5
+ category: credentials
6
+ risk: medium
7
+ parameters:
8
+ - name: required_vcs
9
+ type: AttributeList
10
+ required: true
11
+ validation: "vc-type-id"
12
+ cedar_template: |
13
+ permit (
14
+ principal == Agent::"{{audience_did}}",
15
+ action == Action::"present_vc",
16
+ resource == Credential
17
+ ) when {
18
+ resource.type in {{required_vcs_json}}
19
+ };
20
+ consent_text_template: "Present these credentials: {{required_vcs_display}}."
21
+ obligations_forced:
22
+ - type: audit_level
23
+ params:
24
+ level: verbose
25
+ - type: log_zk_disclosure
26
+ params: {}
27
+ implies: []
28
+ conflicts_with: []
29
+ step_up_required: false
@@ -0,0 +1,31 @@
1
+ id: credentials.proof.zk.request
2
+ version: 1.0.0
3
+ label: Request ZK proof of an attribute
4
+ description: Peer can ask your agent to present a zero-knowledge proof of a single attribute without revealing the underlying credential. Issuer is method-agnostic — any VC issuer that publishes a compatible predicate proof works.
5
+ category: credentials
6
+ risk: medium
7
+ parameters:
8
+ - name: attribute
9
+ type: Enum
10
+ required: true
11
+ validation: ["over_18", "over_21", "us_resident", "verified_human", "country"]
12
+ - name: predicate
13
+ type: Enum
14
+ required: false
15
+ default: "eq"
16
+ validation: ["eq", "gte", "lte", "in"]
17
+ cedar_template: |
18
+ permit (
19
+ principal == Agent::"{{audience_did}}",
20
+ action == Action::"request_zk_proof",
21
+ resource == Credential::"{{attribute}}"
22
+ ) when {
23
+ context.predicate == "{{predicate}}"
24
+ };
25
+ consent_text_template: "Prove to Peer, without revealing details, that you are {{attribute_human}}."
26
+ obligations_forced:
27
+ - type: log_zk_disclosure
28
+ params: {}
29
+ implies: []
30
+ conflicts_with: []
31
+ step_up_required: false
@@ -0,0 +1,36 @@
1
+ id: delegation.forward.task
2
+ version: 1.0.0
3
+ label: Forward task to another agent
4
+ description: Peer can re-delegate a task to a third agent, with automatically attenuated scopes.
5
+ category: delegation
6
+ risk: high
7
+ parameters:
8
+ - name: agent_allowlist
9
+ type: AgentDIDList
10
+ required: true
11
+ validation: "at-least-one"
12
+ - name: scope_attenuation
13
+ type: Enum
14
+ required: true
15
+ default: "read_only"
16
+ validation: ["read_only", "same_scopes", "custom"]
17
+ cedar_template: |
18
+ permit (
19
+ principal == Agent::"{{audience_did}}",
20
+ action == Action::"redelegate",
21
+ resource == Connection::"self"
22
+ ) when {
23
+ context.delegate_target in {{agent_allowlist_json}} &&
24
+ context.attenuation_mode == "{{scope_attenuation}}"
25
+ };
26
+ consent_text_template: "Allow Peer to forward tasks to: {{agent_allowlist_display}}. Forwarded tasks get {{scope_attenuation_human}} access."
27
+ obligations_forced:
28
+ - type: audit_level
29
+ params:
30
+ level: verbose
31
+ - type: notify_principal
32
+ params: {}
33
+ implies: []
34
+ conflicts_with: []
35
+ tier_gate: self_xyz.verified_human
36
+ step_up_required: true
@@ -0,0 +1,31 @@
1
+ id: files.project.files.delete
2
+ version: 1.0.0
3
+ label: Delete files
4
+ description: Peer can delete files in a specific project.
5
+ category: files
6
+ risk: critical
7
+ parameters:
8
+ - name: project_id
9
+ type: ProjectID
10
+ required: true
11
+ cedar_template: |
12
+ permit (
13
+ principal == Agent::"{{audience_did}}",
14
+ action == Action::"delete",
15
+ resource in Project::"{{project_id}}"
16
+ );
17
+ consent_text_template: "Delete files in project {{project_id}} (destructive)."
18
+ obligations_forced:
19
+ - type: require_principal_confirmation
20
+ params:
21
+ max_age_seconds: 0
22
+ - type: audit_level
23
+ params:
24
+ level: verbose
25
+ - type: notify_principal
26
+ params: {}
27
+ implies: []
28
+ conflicts_with:
29
+ - files.share.external
30
+ tier_gate: self_xyz.verified_human
31
+ step_up_required: true
@@ -0,0 +1,22 @@
1
+ id: files.project.files.list
2
+ version: 1.0.0
3
+ label: List files in a project
4
+ description: Peer can list the file names in a specific project, not their contents.
5
+ category: files
6
+ risk: low
7
+ parameters:
8
+ - name: project_id
9
+ type: ProjectID
10
+ required: true
11
+ cedar_template: |
12
+ permit (
13
+ principal == Agent::"{{audience_did}}",
14
+ action == Action::"list",
15
+ resource in Project::"{{project_id}}"
16
+ );
17
+ consent_text_template: "List files in project {{project_id}}."
18
+ obligations_forced: []
19
+ implies:
20
+ - files.project.metadata.read
21
+ conflicts_with: []
22
+ step_up_required: false
@@ -0,0 +1,35 @@
1
+ id: files.project.files.read
2
+ version: 1.0.0
3
+ label: Read file contents
4
+ description: Peer can read the contents of files in a specific project.
5
+ category: files
6
+ risk: medium
7
+ parameters:
8
+ - name: project_id
9
+ type: ProjectID
10
+ required: true
11
+ - name: max_size_mb
12
+ type: Integer
13
+ required: true
14
+ default: 10
15
+ validation: "1..100"
16
+ cedar_template: |
17
+ permit (
18
+ principal == Agent::"{{audience_did}}",
19
+ action in [Action::"read", Action::"list"],
20
+ resource in Project::"{{project_id}}"
21
+ ) when {
22
+ resource.size_bytes <= {{max_size_mb}} * 1048576 &&
23
+ !resource.tags.contains("confidential") &&
24
+ !resource.tags.contains("do-not-share")
25
+ };
26
+ consent_text_template: "Read files in {{project.name}} (up to {{max_size_mb}} MB each; excludes items tagged confidential)."
27
+ obligations_forced:
28
+ - type: audit_level
29
+ params:
30
+ level: verbose
31
+ implies:
32
+ - files.project.files.list
33
+ - files.project.metadata.read
34
+ conflicts_with: []
35
+ step_up_required: false
@@ -0,0 +1,30 @@
1
+ id: files.project.files.summarize
2
+ version: 1.0.0
3
+ label: Summaries only (derive)
4
+ description: Peer receives model-generated summaries of files in a project, never the raw contents.
5
+ category: files
6
+ risk: low
7
+ parameters:
8
+ - name: project_id
9
+ type: ProjectID
10
+ required: true
11
+ - name: max_output_words
12
+ type: Integer
13
+ required: true
14
+ default: 2000
15
+ validation: "100..10000"
16
+ cedar_template: |
17
+ permit (
18
+ principal == Agent::"{{audience_did}}",
19
+ action == Action::"summarize",
20
+ resource in Project::"{{project_id}}"
21
+ );
22
+ consent_text_template: "Summarize files in project {{project_id}} (up to {{max_output_words}} words)."
23
+ obligations_forced:
24
+ - type: summarize_only
25
+ params:
26
+ max_words: "{{max_output_words}}"
27
+ implies:
28
+ - files.project.files.read
29
+ conflicts_with: []
30
+ step_up_required: false
@@ -0,0 +1,34 @@
1
+ id: files.project.files.write
2
+ version: 1.0.0
3
+ label: Create/modify files
4
+ description: Peer can create and modify files in a specific project, up to a maximum size per file.
5
+ category: files
6
+ risk: high
7
+ parameters:
8
+ - name: project_id
9
+ type: ProjectID
10
+ required: true
11
+ - name: max_size_mb
12
+ type: Integer
13
+ required: true
14
+ default: 10
15
+ validation: "1..100"
16
+ cedar_template: |
17
+ permit (
18
+ principal == Agent::"{{audience_did}}",
19
+ action in [Action::"write", Action::"update"],
20
+ resource in Project::"{{project_id}}"
21
+ ) when {
22
+ context.written_size_bytes <= {{max_size_mb}} * 1048576
23
+ };
24
+ consent_text_template: "Create or modify files in {{project_id}} (up to {{max_size_mb}} MB each)."
25
+ obligations_forced:
26
+ - type: audit_level
27
+ params:
28
+ level: verbose
29
+ - type: notify_principal
30
+ params: {}
31
+ implies:
32
+ - files.project.files.read
33
+ conflicts_with: []
34
+ step_up_required: true
@@ -0,0 +1,21 @@
1
+ id: files.project.metadata.read
2
+ version: 1.0.0
3
+ label: Read project metadata
4
+ description: Peer can read a specific project's metadata (name, description, tags), not its files.
5
+ category: files
6
+ risk: low
7
+ parameters:
8
+ - name: project_id
9
+ type: ProjectID
10
+ required: true
11
+ cedar_template: |
12
+ permit (
13
+ principal == Agent::"{{audience_did}}",
14
+ action == Action::"read_metadata",
15
+ resource == Project::"{{project_id}}"
16
+ );
17
+ consent_text_template: "Read metadata for project {{project_id}}."
18
+ obligations_forced: []
19
+ implies: []
20
+ conflicts_with: []
21
+ step_up_required: false