archsight 0.3.2 → 0.3.3

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 (56) hide show
  1. checksums.yaml +4 -4
  2. data/docs/icons.md +26 -0
  3. data/docs/index.md.erb +17 -0
  4. data/docs/modeling.md +147 -2
  5. data/docs/togaf.md +4 -1
  6. data/lib/archsight/annotations/asset_annotations.rb +34 -0
  7. data/lib/archsight/annotations/risk_annotations.rb +21 -0
  8. data/lib/archsight/documentation.rb +3 -2
  9. data/lib/archsight/linter.rb +104 -0
  10. data/lib/archsight/resources/application_component.rb +8 -1
  11. data/lib/archsight/resources/application_event.rb +79 -0
  12. data/lib/archsight/resources/application_service.rb +6 -1
  13. data/lib/archsight/resources/business_actor.rb +9 -1
  14. data/lib/archsight/resources/business_control.rb +10 -2
  15. data/lib/archsight/resources/business_event.rb +79 -0
  16. data/lib/archsight/resources/business_process.rb +8 -1
  17. data/lib/archsight/resources/business_role.rb +69 -0
  18. data/lib/archsight/resources/compliance_evidence.rb +8 -2
  19. data/lib/archsight/resources/data_object.rb +6 -1
  20. data/lib/archsight/resources/implementation_deliverable.rb +62 -0
  21. data/lib/archsight/resources/implementation_event.rb +52 -0
  22. data/lib/archsight/resources/implementation_gap.rb +49 -0
  23. data/lib/archsight/resources/implementation_plateau.rb +61 -0
  24. data/lib/archsight/resources/implementation_work_package.rb +83 -0
  25. data/lib/archsight/resources/motivation_assessment.rb +121 -0
  26. data/lib/archsight/resources/motivation_constraint.rb +7 -1
  27. data/lib/archsight/resources/motivation_driver.rb +50 -0
  28. data/lib/archsight/resources/motivation_goal.rb +13 -1
  29. data/lib/archsight/resources/motivation_principle.rb +75 -0
  30. data/lib/archsight/resources/motivation_requirement.rb +12 -2
  31. data/lib/archsight/resources/motivation_stakeholder.rb +7 -0
  32. data/lib/archsight/resources/page.rb +5 -0
  33. data/lib/archsight/resources/technology_event.rb +80 -0
  34. data/lib/archsight/resources/technology_node.rb +7 -1
  35. data/lib/archsight/version.rb +1 -1
  36. data/lib/archsight/web/public/vue/{ApiDocsPage-DoOxKjG0.js → ApiDocsPage-BgqnQgwa.js} +1 -1
  37. data/lib/archsight/web/public/vue/{DocPage-CfsC3CeQ.js → DocPage-CNO71nBH.js} +1 -1
  38. data/lib/archsight/web/public/vue/{EditorPage-CsJA0q8n.js → EditorPage-DR0FCNTz.js} +1 -1
  39. data/lib/archsight/web/public/vue/{ErrorPage-OJpJz9df.js → ErrorPage-BfYArv6s.js} +1 -1
  40. data/lib/archsight/web/public/vue/{GraphView-CBq6oFRV.js → GraphView-BVTW30Ak.js} +1 -1
  41. data/lib/archsight/web/public/vue/HomePage-Wk9P4Pma.js +2 -0
  42. data/lib/archsight/web/public/vue/{InstanceRouter-DQz-SsQq.js → InstanceRouter-BV8ycydz.js} +1 -1
  43. data/lib/archsight/web/public/vue/{KindList-4q0K9Cll.js → KindList-C8yMsN5J.js} +1 -1
  44. data/lib/archsight/web/public/vue/{PageView-DzeGnvoS.js → PageView-BaN6TyJB.js} +1 -1
  45. data/lib/archsight/web/public/vue/{QueryError-kg6Yf-pW.js → QueryError-D790wH-a.js} +1 -1
  46. data/lib/archsight/web/public/vue/{ResourceList-Df_0e0qt.js → ResourceList-D-66nas2.js} +1 -1
  47. data/lib/archsight/web/public/vue/{SearchResults-CyPUZZSC.css → SearchResults-BewvsfOc.css} +1 -1
  48. data/lib/archsight/web/public/vue/SearchResults-CHyqIerQ.js +1 -0
  49. data/lib/archsight/web/public/vue/{WikiPage-DrvCHwJ7.js → WikiPage-D2svpk6B.js} +1 -1
  50. data/lib/archsight/web/public/vue/{index-D0Q5GZRs.js → index-BXXkUK1V.js} +2 -2
  51. data/lib/archsight/web/public/vue/{index-oF-iyZvk.css → index-Cov1SnzY.css} +1 -1
  52. data/lib/archsight/web/public/vue/{useGraphviz-DweKV7Kg.js → useGraphviz-DlSnFeCL.js} +12 -0
  53. data/lib/archsight/web/public/vue.html +2 -2
  54. metadata +32 -18
  55. data/lib/archsight/web/public/vue/HomePage-BwgMLgVC.js +0 -2
  56. data/lib/archsight/web/public/vue/SearchResults-CKgY6_wH.js +0 -1
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 464d36ecbae64b55e25554f9d60d9c208fb2477ba1910f2318c415eef2cea018
4
- data.tar.gz: e423de1798a1a0fc99f16220051139800780e6bd9f01b096bce378dda1ccb25e
3
+ metadata.gz: b601281c3dc26c95647876457b96e590146aee23b762d14034ed2ae5f0953710
4
+ data.tar.gz: 7c271d26e8def3f7e85d82210ebda0d45628e280c1bb58832b81f2900c3e1097
5
5
  SHA512:
6
- metadata.gz: 0eb109e3f462b8ec1a23a17ab8c95d5d8bc176a5b54d038e47fa9dcf383e2597c9cc4a540efb1bd876714b279486dfd5a74d1bf1adc8c435a64db07913128890
7
- data.tar.gz: 7ce31438036e3addcc8bda4e3587165f13b31399bd7a416323747d1552d9ae910c3e53191f8f7689f7b01a3d84508b9a32cf6cf7486fbb9bde3c0920560283bd
6
+ metadata.gz: 416c904c7b8ecc1c44527b226fe7e6c7697c03d905d855db532bb80f1bd5ff0ff1277c770947eed411a6ca7cae7dafd8e32085690d72a4235c73bd4c1f35950b
7
+ data.tar.gz: 9c22b78187060cdc3606b4f423a38b79f84edcee6cb1d6f1446348a9da46dc088bedb4f537c809aad28c2db33f875d490637c4dcc13b57b4ee0ccc76822a0193
data/docs/icons.md CHANGED
@@ -11,25 +11,51 @@ Current icon assignments for each resource type:
11
11
  | ApplicationInterface | `usb` | <i class="iconoir-usb"></i> |
12
12
  | ApplicationService | `cube` | <i class="iconoir-cube"></i> |
13
13
  | BusinessActor | `community` | <i class="iconoir-community"></i> |
14
+ | ApplicationEvent | `bell-notification` | <i class="iconoir-bell-notification"></i> |
14
15
  | BusinessControl | `shield-search` | <i class="iconoir-shield-search"></i> |
16
+ | BusinessEvent | `flash` | <i class="iconoir-flash"></i> |
17
+ | BusinessRole | `user-badge-check` | <i class="iconoir-user-badge-check"></i> |
15
18
  | BusinessProcess | `kanban-board` | <i class="iconoir-kanban-board"></i> |
16
19
  | BusinessProduct | `box-iso` | <i class="iconoir-box-iso"></i> |
17
20
  | ComplianceEvidence | `shield-check` | <i class="iconoir-shield-check"></i> |
18
21
  | DataObject | `database` | <i class="iconoir-database"></i> |
19
22
  | ApplicationComponent | `component` | <i class="iconoir-component"></i> |
20
23
  | TechnologySystemSoftware | `terminal-tag` | <i class="iconoir-terminal-tag"></i> |
24
+ | MotivationAssessment | `stats-up-square` | <i class="iconoir-stats-up-square"></i> |
25
+ | MotivationDriver | `fire-flame` | <i class="iconoir-fire-flame"></i> |
26
+ | ImplementationDeliverable | `package` | <i class="iconoir-package"></i> |
27
+ | ImplementationEvent | `calendar-check` | <i class="iconoir-calendar-check"></i> |
28
+ | ImplementationGap | `git-compare` | <i class="iconoir-git-compare"></i> |
29
+ | ImplementationPlateau | `packages` | <i class="iconoir-packages"></i> |
30
+ | ImplementationWorkPackage | `hammer` | <i class="iconoir-hammer"></i> |
21
31
  | MotivationGoal | `archery` | <i class="iconoir-archery"></i> |
22
32
  | MotivationOutcome | `badge-check` | <i class="iconoir-badge-check"></i> |
33
+ | MotivationPrinciple | `book` | <i class="iconoir-book"></i> |
23
34
  | MotivationRequirement | `task-list` | <i class="iconoir-task-list"></i> |
24
35
  | MotivationConstraint | `prohibition` | <i class="iconoir-prohibition"></i> |
25
36
  | MotivationStakeholder | `user-crown` | <i class="iconoir-user-crown"></i> |
26
37
  | TechnologyNode | `server-connection` | <i class="iconoir-server-connection"></i> |
27
38
  | StrategyCapability | `strategy` | <i class="iconoir-strategy"></i> |
28
39
  | TechnologyArtifact | `puzzle` | <i class="iconoir-puzzle"></i> |
40
+ | TechnologyEvent | `warning-triangle` | <i class="iconoir-warning-triangle"></i> |
29
41
  | TechnologyInterface | `data-transfer-both` | <i class="iconoir-data-transfer-both"></i> |
30
42
  | TechnologyService | `cloud` | <i class="iconoir-cloud"></i> |
31
43
  | View | `view-grid` | <i class="iconoir-view-grid"></i> |
32
44
 
45
+ ## Layer Colours
46
+
47
+ Icons and graph nodes take the colour of their layer.
48
+
49
+ | Layer | Colour | Graph (light) | Icon |
50
+ |-------|--------|---------------|------|
51
+ | Strategy | orange | `#F4A261` | `#D4824A` |
52
+ | Motivation | purple | `#CE93D8` | `#AB47BC` |
53
+ | Business | yellow | `#F9DC5C` | `#D4B83C` |
54
+ | Application | blue | `#6CBEED` | `#4A9ECD` |
55
+ | Technology | green | `#8AC926` | `#7AB316` |
56
+ | Implementation & Migration | rose | `#F48FB1` | `#E0527F` |
57
+ | Other | gray | `#CCCCCC` | `#999999` |
58
+
33
59
  ## Icon Categories
34
60
 
35
61
  ### Technology & Development
data/docs/index.md.erb CHANGED
@@ -31,15 +31,20 @@ Resources representing stakeholders, goals, outcomes, requirements, and constrai
31
31
  - [MotivationOutcome](/doc/resources/motivation_outcome) - End results or consequences
32
32
  - [MotivationRequirement](/doc/resources/motivation_requirement) - Compliance, legal and functional requirements
33
33
  - [MotivationConstraint](/doc/resources/motivation_constraint) - Limitations and restrictions
34
+ - [MotivationDriver](/doc/resources/motivation_driver) - Threats, opportunities and other drivers
35
+ - [MotivationAssessment](/doc/resources/motivation_assessment) - Risks, vulnerabilities and findings
36
+ - [MotivationPrinciple](/doc/resources/motivation_principle) - Policies and principles
34
37
 
35
38
  ### Business Layer
36
39
 
37
40
  Resources representing business processes, actors, products, and the controls that guide processes.
38
41
 
39
42
  - [BusinessActor](/doc/resources/business_actor) - Teams and organizations
43
+ - [BusinessRole](/doc/resources/business_role) - Responsibilities that actors take on
40
44
  - [BusinessProcess](/doc/resources/business_process) - Structured business workflows
41
45
  - [BusinessProduct](/doc/resources/business_product) - Products offered to customers
42
46
  - [BusinessControl](/doc/resources/business_control) - Controls that guide business processes
47
+ - [BusinessEvent](/doc/resources/business_event) - Threat events, loss events and triggers
43
48
 
44
49
  ### Strategy Layer
45
50
 
@@ -54,6 +59,7 @@ Resources representing application services, components, and interfaces.
54
59
  - [ApplicationService](/doc/resources/application_service) - High-level application services
55
60
  - [ApplicationComponent](/doc/resources/application_component) - Logical parts of services
56
61
  - [ApplicationInterface](/doc/resources/application_interface) - APIs and interfaces between components
62
+ - [ApplicationEvent](/doc/resources/application_event) - Threat events, loss events and triggers of applications
57
63
  - [DataObject](/doc/resources/data_object) - Data structures and schemas
58
64
 
59
65
  ### Technology Layer
@@ -63,9 +69,20 @@ Resources representing technology infrastructure and artifacts.
63
69
  - [TechnologyService](/doc/resources/technology_service) - Infrastructure services
64
70
  - [TechnologyArtifact](/doc/resources/technology_artifact) - Source code repositories
65
71
  - [TechnologyInterface](/doc/resources/technology_interface) - Technical interfaces
72
+ - [TechnologyEvent](/doc/resources/technology_event) - Infrastructure events, scan findings and outages
66
73
  - [TechnologySystemSoftware](/doc/resources/technology_system_software) - Logical infrastructure components
67
74
  - [TechnologyNode](/doc/resources/technology_node) - Physical infrastructure
68
75
 
76
+ ### Implementation & Migration Layer
77
+
78
+ Resources representing change: work, results, milestones and the states of the architecture between them.
79
+
80
+ - [ImplementationWorkPackage](/doc/resources/implementation_work_package) - Projects, measures and remediation
81
+ - [ImplementationDeliverable](/doc/resources/implementation_deliverable) - Results of work packages
82
+ - [ImplementationEvent](/doc/resources/implementation_event) - Milestones, go-lives and deadlines
83
+ - [ImplementationPlateau](/doc/resources/implementation_plateau) - Baseline, transition and target states
84
+ - [ImplementationGap](/doc/resources/implementation_gap) - Differences between plateaus
85
+
69
86
  ### Other
70
87
 
71
88
  - [ComplianceEvidence](/doc/resources/compliance_evidence) - Evidence for compliance requirements
data/docs/modeling.md CHANGED
@@ -18,6 +18,34 @@ Application Layer What software supports the business
18
18
  Technology Layer How software is built and deployed
19
19
  ```
20
20
 
21
+ ## Direction of Relations
22
+
23
+ Model and read the architecture **top-down**: Motivation, Strategy, Business, Application, Technology; the
24
+ Implementation & Migration layer describes change across all of them. A relation is written on an element and points
25
+ to what that element depends on, is served by, or is answered by. Following relations from a high-level element
26
+ therefore walks down to people, code and infrastructure, and the relations form a DAG: nothing may lead back to where
27
+ it started. `archsight lint` reports every cycle (only `dependsOn` is exempt, because components may depend on each
28
+ other at runtime).
29
+
30
+ There are two families of verbs:
31
+
32
+ | Family | Verbs | Written on | Points to |
33
+ |--------|-------|------------|-----------|
34
+ | Responsibility and provider (down) | `performedBy`, `ownedBy`, `executedBy`, `servedBy`, `guidedBy`, `maintainedBy`, `contributedBy`, `hasConcern`, `realizedThrough`, `exposes`, `mitigatedBy`, `influences`, `triggers`, `affects`, `assesses`, `contains`, `closedBy`, `compares` | the element that needs, uses or is concerned with something | what provides it or is responsible for it |
35
+ | Realization (up) | `realizes`, `partiallyRealizes`, `plans`, `satisfies`, `evidencedBy` (on the evidenced element), `provides` | the concrete element | the abstract element it answers to (requirement, goal, capability, plateau) |
36
+
37
+ Rules:
38
+
39
+ - A pair of kinds never has the same relation in both directions: a goal `realizes` a requirement, a requirement does not
40
+ `realize` a goal. Reverse relations are shown for free as incoming relations.
41
+ - Responsibility ends at the actor: process, control, risk, policy, work package point to a `BusinessRole`, the role
42
+ points to the `BusinessActor` that holds it, and the actor points to nothing further.
43
+ - The docs draw realization chains top-down ("Requirement, down to Service") while the data is stored on the concrete
44
+ element, so the file of a service says what it realizes.
45
+ - `mentions` and `depicts` are not part of this structure. They are derived from the text and diagrams of a resource
46
+ (never written in a file) and show how things are linked sideways, in prose and pictures. They neither follow nor
47
+ contradict the direction above and are left out of the cycle check.
48
+
21
49
  ## Starting Points
22
50
 
23
51
  ### Top-Down Modeling
@@ -54,6 +82,9 @@ Model **why** the architecture exists.
54
82
  | MotivationOutcome | For measurable results ("99.9% availability", "Sub-100ms response") |
55
83
  | MotivationRequirement | For must-have capabilities (compliance, functional needs) |
56
84
  | MotivationConstraint | For limitations (budget, regulations, technical debt) |
85
+ | MotivationDriver | For threats, opportunities, regulation and market forces that motivate action (`driver/type`) |
86
+ | MotivationAssessment | For risks, vulnerabilities, findings and supplier or protection-need analyses (`assessment/type`) |
87
+ | MotivationPrinciple | For policies, guidelines and architecture principles (`principle/type`) |
57
88
 
58
89
  **Example chain:** Stakeholder "Security Team" → hasConcern → Goal "Achieve Compliance" → realizes → Requirement "Encrypt data at rest"
59
90
 
@@ -64,13 +95,33 @@ Model **who** does **what** in business terms.
64
95
  | Resource | When to Use |
65
96
  |----------|-------------|
66
97
  | BusinessActor | For teams, departments, or organizations |
98
+ | BusinessRole | For responsibilities held by actors: control owner, risk owner, information security officer (`role/type`) |
67
99
  | BusinessProcess | For workflows that produce business value |
68
100
  | BusinessProduct | For offerings to customers (cloud services, APIs) |
69
101
  | BusinessControl | For controls that guide a process (access review, change approval), with an owner and executors |
102
+ | BusinessEvent | For things that happen in the business: threat events, loss events, incidents, triggers (`event/type`) |
103
+
104
+ **Example chain:** Process "Incident Response" → performedBy → Actor "Platform Team"; Process "Incident Response" → servedBy → Service "Monitoring"
105
+
106
+ **Roles:** Process "Incident Response" → performedBy → Role "Incident Manager" → performedBy → Actor "Platform Team". Controls, risks, policies and work packages use `ownedBy` (and controls `executedBy`) the same way. Use a role where the responsibility has a name of its own and should survive a change of team; pointing straight at an actor stays valid.
107
+
108
+ **Controls:** Process "Incident Response" → guidedBy → Control "Escalation Review" → ownedBy / executedBy → Role or Actor. How controls, requirements and evidence fit together is described under Relation Patterns below.
70
109
 
71
- **Example chain:** Actor "Platform Team" → performedBy → Process "Incident Response" → servedBy → Service "Monitoring"
110
+ ### Implementation & Migration Layer
111
+
112
+ Model **change**: what is done, what it delivers and how the architecture looks before and after.
113
+
114
+ | Resource | When to Use |
115
+ |----------|-------------|
116
+ | ImplementationWorkPackage | For projects, measures, remediation of risks and findings, audit programmes (`workpackage/type`, status, due date) |
117
+ | ImplementationDeliverable | For the results of work packages: documents, systems, process changes, evidence (`deliverable/type`) |
118
+ | ImplementationEvent | For milestones, go-lives and deadlines (`event/type`) |
119
+ | ImplementationPlateau | For a state of the architecture: baseline, transition, target (`plateau/type`) |
120
+ | ImplementationGap | For the difference between two plateaus (`gap/status`, `gap/impact`) |
72
121
 
73
- **Controls:** Process "Incident Response" → guidedBy → Control "Escalation Review" → ownedBy / executedBy → Actor "Platform Team". How controls, requirements and evidence fit together is described under Relation Patterns below.
122
+ **Migration path:** Plateau "Baseline" → triggers → Plateau "Target"; Gap → compares → both plateaus; Work Package → realizes → Deliverable → realizes → Plateau "Target"; Gap → closedBy → Work Package.
123
+
124
+ **Remediation:** Assessment "Risk" → mitigatedBy → Work Package → realizes → Deliverable (type `evidence`) → realizes → ComplianceEvidence. Group by `risk/domain` to see the plan of one domain, filter by `workpackage/status` and `workpackage/due` for what is open or late.
74
125
 
75
126
  ### Strategy Layer
76
127
 
@@ -189,6 +240,100 @@ spec:
189
240
  evidencedBy: { complianceEvidences: [Evidence:DeploymentAuditLog] }
190
241
  ```
191
242
 
243
+ ### Security and Risk
244
+
245
+ Security and risk are modelled with the elements above, following the risk and security overlay of the Open Group
246
+ white paper [Modeling Enterprise Risk Management and Security with the ArchiMate Language](#reference). There is no
247
+ separate security layer: a concept is an ordinary element that carries a **type** (a specialization, the paper's
248
+ "stereotype") plus profile annotations. The type is a filterable annotation, so views, queries and lists can group by it.
249
+
250
+ | Security concept | Kind | Type annotation | Notes |
251
+ |------------------|------|-----------------|-------|
252
+ | Threat (circumstance) | `MotivationDriver` | `driver/type: threat` | also opportunity, regulation, market |
253
+ | Threat agent | `BusinessActor`, `ApplicationComponent`, `TechnologyNode` | none | the `causedBy` of an event |
254
+ | Threat event | `BusinessEvent`, `ApplicationEvent`, `TechnologyEvent` | `event/type: threat-event` or `attack` | `attack` = intentional |
255
+ | Loss event, incident | the three event kinds | `event/type: loss-event` or `incident` | the layer says where it happens |
256
+ | Risk | `MotivationAssessment` | `assessment/type: risk` | initial and residual profile, `risk/treatment` |
257
+ | Vulnerability | `MotivationAssessment` | `assessment/type: vulnerability` | `assesses` the assets it is found on |
258
+ | Control objective | `MotivationGoal` | `goal/type: control-objective` | the risk is `mitigatedBy` it |
259
+ | Control measure | `MotivationRequirement` | `requirement/type: control-measure` | a goal `realizes` it; the risk can be `mitigatedBy` it |
260
+ | Control implementation | `BusinessControl`, applications, nodes, processes | none | `satisfies` / `realizes` the measure |
261
+ | Proof of the control | `ComplianceEvidence` | `evidence/type` | `evidence/status: not-applicable` where the requirement does not apply |
262
+ | Asset at risk | any application, technology, data or process kind | `asset/value`, `asset/confidentiality`, `asset/integrity`, `asset/availability` | the protection need (BSI Schutzbedarf) |
263
+ | Policy (design level) | `MotivationPrinciple` | `principle/type: security-policy` or `risk-policy` | status, validity, framework mapping |
264
+ | Operational policy, regulation | `MotivationConstraint` | none | the paper has no element for operational policy |
265
+ | Risk domain | none; annotation `risk/domain` | `risk/domain`, `risk/category` | group by it with a query or a `View` |
266
+
267
+ The chain, as in the paper's Coldhard Steel example:
268
+
269
+ ```
270
+ MotivationDriver (threat) ──influences──→ MotivationAssessment (risk) ──mitigatedBy──→ MotivationGoal (control objective)
271
+ │ triggers │ assesses │ realizes
272
+ ↓ ↓ ↓
273
+ BusinessEvent (loss event) ←──influences── MotivationAssessment (vulnerability) MotivationRequirement (control measure)
274
+ ↑ triggers ↑ satisfies / realizes
275
+ TechnologyEvent / ApplicationEvent (threat event, attack) BusinessControl / asset ──evidencedBy──→ ComplianceEvidence
276
+ ```
277
+
278
+ ```yaml
279
+ kind: MotivationDriver
280
+ metadata: { name: Threat:Intrusion, annotations: { driver/type: threat } }
281
+ spec:
282
+ influences: { motivationAssessments: [Risk:Intrusion] }
283
+ triggers: { businessEvents: [Loss:DataLeak] }
284
+ ---
285
+ kind: MotivationAssessment
286
+ metadata:
287
+ name: Risk:Intrusion
288
+ annotations:
289
+ assessment/type: risk
290
+ risk/initial-likelihood: high
291
+ risk/residual-likelihood: low
292
+ risk/treatment: mitigate
293
+ risk/domain: customer-data
294
+ spec:
295
+ ownedBy: { businessRoles: [Role:RiskOwner] }
296
+ assesses: { technologyNodes: [Node:Web1] }
297
+ mitigatedBy: { goals: [Objective:ReduceExposure], businessControls: [Control:FirewallReview] }
298
+ ---
299
+ kind: MotivationGoal
300
+ metadata: { name: Objective:ReduceExposure, annotations: { goal/type: control-objective } }
301
+ spec:
302
+ realizes: { motivationRequirements: [Measure:Firewall] }
303
+ ---
304
+ kind: MotivationRequirement
305
+ metadata: { name: Measure:Firewall, annotations: { requirement/type: control-measure } }
306
+ spec: {}
307
+ ---
308
+ kind: BusinessControl
309
+ metadata: { name: Control:FirewallReview }
310
+ spec:
311
+ ownedBy: { businessRoles: [Role:ControlOwner] }
312
+ satisfies: { motivationRequirements: [Measure:Firewall] }
313
+ ```
314
+
315
+ How to model it:
316
+
317
+ - **Events and their types.** A threat event `triggers` a loss event; the three event kinds (business, application,
318
+ technology) say on which level it happens and a technology event may trigger an application or business event. Use
319
+ `event/type` to tell threat events, attacks, loss events, incidents, opportunity events, audits, scans and changes apart.
320
+ - **Vulnerability scan.** One `MotivationAssessment` of type `vulnerability` per finding, `assesses` every node it was
321
+ found on, `influences` the loss events and risks it makes possible. Business impact follows from the model: the node
322
+ serves services, services serve processes.
323
+ - **Grouping (risk domains).** ArchiMate has no domain element; set `risk/domain` (and `risk/category`: hazard,
324
+ financial, operational, strategic, compliance, security) on events, assessments, drivers, requirements, controls and
325
+ assets, and query or build a `View` per domain to see its threats, risks, measures and assets together.
326
+ - **Policies.** The text of a policy is a `Page`; the structured statement (owner, validity, status, framework) is a
327
+ `MotivationPrinciple` that links to the page with `[[Page]]`.
328
+ - **Initial and residual risk.** Record both on the assessment (`risk/initial-*`, `risk/residual-*`) and the decision
329
+ in `risk/treatment`.
330
+
331
+ <a id="reference"></a>
332
+ **Reference:** Band, Engelsman, Feltus, González Paredes, Hietala, Jonkers, Massart,
333
+ [Modeling Enterprise Risk Management and Security with the ArchiMate Language](https://pure.unamur.be/ws/files/12366722/Modeling_Enterprise_Risk_Management_and_Secutity_with_the_ArchiMate_Language.pdf),
334
+ The Open Group white paper (ArchiMate 2.1). For the NIST OSCAL vocabulary used for names of assessment and evidence
335
+ fields see [OSCAL](https://pages.nist.gov/OSCAL/learn/concepts/layer/).
336
+
192
337
  ### Compliance Chain
193
338
 
194
339
  Shows how requirements are satisfied:
data/docs/togaf.md CHANGED
@@ -122,12 +122,15 @@ The metamodel defines architectural entities and their relationships across all
122
122
 
123
123
  **Cross-Cutting:**
124
124
 
125
- - **Principle**, **Constraint**, **Requirement**, **Gap**, **Work Package**, **Location**
125
+ - **Principle**, **Constraint**, **Requirement**, **Location**
126
+ - **Gap**, **Work Package**, **Deliverable**, **Plateau**, **Implementation Event**: the Implementation & Migration layer (`ImplementationGap`, `ImplementationWorkPackage`, `ImplementationDeliverable`, `ImplementationPlateau`, `ImplementationEvent`)
126
127
 
127
128
  **Governance:**
128
129
 
129
130
  - **Control**: a decision-making step with accountability and authority, applied to a process or function. ArchiMate has no element for it; Archsight models it as `BusinessControl`, which a `BusinessProcess` is `guidedBy`
130
131
 
132
+ **Risk and security:** the Open Group overlay (*Modeling Enterprise Risk Management and Security with the ArchiMate Language*) maps threats to **Driver** (`MotivationDriver`), threat and loss events to **Business/Application/Technology Event**, risks and vulnerabilities to **Assessment** (`MotivationAssessment`), control objectives to **Goal**, control measures to **Requirement** and policies to **Principle** (`MotivationPrinciple`), each with a type annotation. See [Modeling Guide](modeling.md#security-and-risk). How relations are directed (top-down, DAG) is described under [Direction of Relations](modeling.md#direction-of-relations).
133
+
131
134
  ### Critical Relationships
132
135
 
133
136
  1. **Traceability**: Drivers → Goals → Objectives → Course of Action → Business Elements → Applications → Technology
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Asset module adds the asset profile of an asset at risk: its value and its protection need (BSI "Schutzbedarf")
4
+ module Archsight::Annotations::Asset
5
+ NEED = %w[normal high very-high].freeze
6
+
7
+ def self.included(base)
8
+ base.class_eval do
9
+ annotation "asset/value",
10
+ description: "Value of the asset to the organization",
11
+ title: "Asset value",
12
+ enum: %w[low medium high critical],
13
+ filter: :word
14
+
15
+ annotation "asset/confidentiality",
16
+ description: "Protection need for confidentiality",
17
+ title: "Confidentiality need",
18
+ enum: Archsight::Annotations::Asset::NEED,
19
+ filter: :word
20
+
21
+ annotation "asset/integrity",
22
+ description: "Protection need for integrity",
23
+ title: "Integrity need",
24
+ enum: Archsight::Annotations::Asset::NEED,
25
+ filter: :word
26
+
27
+ annotation "asset/availability",
28
+ description: "Protection need for availability",
29
+ title: "Availability need",
30
+ enum: Archsight::Annotations::Asset::NEED,
31
+ filter: :word
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Risk module adds the annotations that group security and risk resources: the paper's "risk domain" and the
4
+ # classification of the risk
5
+ module Archsight::Annotations::Risk
6
+ def self.included(base)
7
+ base.class_eval do
8
+ annotation "risk/domain",
9
+ description: "Risk domain(s) the resource belongs to (comma-separated); groups threats, risks, " \
10
+ "vulnerabilities, measures and assets that share a context",
11
+ title: "Risk domain",
12
+ filter: :list
13
+
14
+ annotation "risk/category",
15
+ description: "Classification of the risk (CAS enterprise risk classification, plus compliance and security)",
16
+ title: "Risk category",
17
+ enum: %w[hazard financial operational strategic compliance security],
18
+ filter: :word
19
+ end
20
+ end
21
+ end
@@ -7,7 +7,7 @@ module Archsight
7
7
  # Documentation generates markdown documentation for architecture resources
8
8
  class Documentation
9
9
  # Layer display order (top to bottom)
10
- LAYER_ORDER = %w[motivation strategy business application technology].freeze
10
+ LAYER_ORDER = %w[motivation strategy business application technology implementation].freeze
11
11
 
12
12
  # Layer display names
13
13
  LAYER_NAMES = {
@@ -15,7 +15,8 @@ module Archsight
15
15
  "strategy" => "Strategy Layer",
16
16
  "business" => "Business Layer",
17
17
  "application" => "Application Layer",
18
- "technology" => "Technology Layer"
18
+ "technology" => "Technology Layer",
19
+ "implementation" => "Implementation & Migration Layer"
19
20
  }.freeze
20
21
 
21
22
  # Resource kinds to exclude from the diagram
@@ -8,6 +8,12 @@ module Archsight
8
8
  # Valid @component references in View annotations
9
9
  VALID_COMPONENTS = %w[activity git jira languages owner repositories status].freeze
10
10
 
11
+ # Relations the cycle check leaves out. Relations are followed from the dependent to what it relies on, so
12
+ # the declared ones form a DAG; `dependsOn` is the exception because components may depend on each other at
13
+ # runtime. The derived relations (`mentions`, `depicts`) are sideways views and are not declared, so they
14
+ # never enter the check.
15
+ CYCLE_EXEMPT_VERBS = %i[dependsOn].freeze
16
+
11
17
  def initialize(database)
12
18
  @database = database
13
19
  @errors = []
@@ -22,6 +28,7 @@ module Archsight
22
28
  validate_menu(instance) if instance.klass == "PageMenu"
23
29
  end
24
30
  end
31
+ validate_relation_cycles
25
32
 
26
33
  @errors
27
34
  end
@@ -79,6 +86,103 @@ module Archsight
79
86
  nil
80
87
  end
81
88
 
89
+ # Declared relations must not lead back to where they started (see the "Direction of Relations" modeling guide)
90
+ def validate_relation_cycles
91
+ graph = relation_graph
92
+ strongly_connected_groups(graph).each do |group|
93
+ cycle = cycle_through(group.first, group, graph)
94
+ names = cycle.map { |step| step[:to].name }
95
+ start = group.first
96
+ path = ([start.name] + names).zip(cycle.map { |step| step[:verb] }).flat_map { |name, verb| [name, verb && "-#{verb}->"] }.compact
97
+ @errors << "#{start.path_ref}: #{start.klass} '#{start.name}' is part of a relation cycle (#{path.join(" ")})"
98
+ end
99
+ end
100
+
101
+ # { instance => [{ verb:, to: }] } over the declared relations
102
+ def relation_graph
103
+ graph = {}
104
+ @database.instances.each_value do |instances_hash|
105
+ instances_hash.each_value do |instance|
106
+ graph[instance] = instance.class.declared_relations.flat_map do |verb, key, _kind|
107
+ next [] if CYCLE_EXEMPT_VERBS.include?(verb)
108
+
109
+ instance.relations(verb, key).map { |target| { verb: verb, to: target } }
110
+ end
111
+ end
112
+ end
113
+ graph
114
+ end
115
+
116
+ # Groups of instances that reach each other (iterative Tarjan, the graph can be deep); a single instance counts
117
+ # only when it points at itself
118
+ def strongly_connected_groups(graph)
119
+ index = {}
120
+ lowlink = {}
121
+ on_stack = {}
122
+ stack = []
123
+ groups = []
124
+ counter = 0
125
+
126
+ graph.each_key do |root|
127
+ next if index.key?(root)
128
+
129
+ work = [[root, 0]]
130
+ until work.empty?
131
+ node, edge = work.last
132
+ if edge.zero?
133
+ index[node] = lowlink[node] = counter
134
+ counter += 1
135
+ stack << node
136
+ on_stack[node] = true
137
+ end
138
+
139
+ edges = graph[node] || []
140
+ if edge < edges.length
141
+ work.last[1] += 1
142
+ target = edges[edge][:to]
143
+ if !index.key?(target)
144
+ work << [target, 0]
145
+ elsif on_stack[target]
146
+ lowlink[node] = [lowlink[node], index[target]].min
147
+ end
148
+ else
149
+ work.pop
150
+ lowlink[work.last.first] = [lowlink[work.last.first], lowlink[node]].min unless work.empty?
151
+ next unless lowlink[node] == index[node]
152
+
153
+ group = []
154
+ loop do
155
+ member = stack.pop
156
+ on_stack[member] = false
157
+ group << member
158
+ break if member.equal?(node)
159
+ end
160
+ groups << group if group.length > 1 || edges.any? { |e| e[:to].equal?(node) }
161
+ end
162
+ end
163
+ end
164
+ groups
165
+ end
166
+
167
+ # One concrete cycle through `start` inside its group: [{ verb:, to: }, ...] ending at `start`
168
+ def cycle_through(start, group, graph)
169
+ members = group.to_h { |member| [member, true] }
170
+ queue = [[start, []]]
171
+ seen = { start => true }
172
+ until queue.empty?
173
+ node, path = queue.shift
174
+ graph[node].each do |edge|
175
+ next unless members[edge[:to]]
176
+ return path + [edge] if edge[:to].equal?(start)
177
+ next if seen[edge[:to]]
178
+
179
+ seen[edge[:to]] = true
180
+ queue << [edge[:to], path + [edge]]
181
+ end
182
+ end
183
+ []
184
+ end
185
+
82
186
  def validate_instance_annotations(instance)
83
187
  instance.annotations.each do |key, value|
84
188
  # Find matching annotation definition (handles both exact and pattern matches)
@@ -2,7 +2,7 @@
2
2
 
3
3
  # ApplicationComponent a part of the ApplicationService
4
4
  class Archsight::Resources::ApplicationComponent < Archsight::Resources::Base
5
- include_annotations :git, :architecture, :generated, :backup
5
+ include_annotations :git, :architecture, :generated, :backup, :asset, :risk
6
6
 
7
7
  description <<~MD
8
8
  Represents a logical part of an application service that can be deployed independently.
@@ -24,6 +24,13 @@ class Archsight::Resources::ApplicationComponent < Archsight::Resources::Base
24
24
  - Backend components
25
25
  - Frontend applications
26
26
  - Background workers
27
+
28
+ ## Security and risk modelling
29
+
30
+ - **Asset at risk:** set `asset/value` and the protection needs; `assesses` from a vulnerability or risk.
31
+ - **Control implementation:** a component that implements a control measure `realizes` the requirement and is
32
+ `evidencedBy` evidence.
33
+ - **Threat agent:** a component can be the `causedBy` of an event (a compromised service).
27
34
  MD
28
35
 
29
36
  icon "component"
@@ -0,0 +1,79 @@
1
+ # frozen_string_literal: true
2
+
3
+ # ApplicationEvent represents an application event: something that happens in an application and triggers or interrupts application behavior
4
+ class Archsight::Resources::ApplicationEvent < Archsight::Resources::Base
5
+ include_annotations :git, :architecture, :risk
6
+
7
+ description <<~MD
8
+ Represents an application event: something that happens in an application and triggers or interrupts application behavior.
9
+
10
+ ## ArchiMate Definition
11
+
12
+ **Layer:** Application
13
+ **Aspect:** Behavior
14
+
15
+ An event is something that happens and influences behavior. It does not last: it triggers or interrupts
16
+ processes and services. In the risk and security overlay of the Open Group paper (*Modeling Enterprise Risk
17
+ Management and Security with the ArchiMate Language*) a threat event and a loss event are events that carry a
18
+ type; set `event/type` to say which.
19
+
20
+ ## Usage
21
+
22
+ Use ApplicationEvent for events on the application level:
23
+
24
+ - Threat events and loss events of applications (an exploit of a service, a burst of failed logins, a data leak)
25
+ - Security alerts raised by an application
26
+ - Triggers of application services (a message arrives, a job is scheduled)
27
+
28
+ ## Event types
29
+
30
+ - `threat-event`: an event with the potential to harm an asset; it can trigger a loss event
31
+ - `attack`: a threat event caused by intentional malicious activity
32
+ - `loss-event`: an event that harms an asset (a hazard materialises, a vulnerability is exploited)
33
+ - `incident`: a loss event that has happened
34
+ - `opportunity-event`: an event that can add value
35
+ - `audit`, `scan`, `change`: events that produce assessments or alter the architecture
36
+ - `other`
37
+
38
+ Filter, group and query by `event/type`, `risk/domain` and `risk/category` to see, for example, every loss
39
+ event of a risk domain.
40
+
41
+ ## How it connects
42
+
43
+ - A threat event `triggers` a loss event or a process or service; threat and loss events may sit on different
44
+ layers (a technology event triggers an application or business event)
45
+ - `causedBy` the threat agent (an actor, component or node)
46
+ - `affects` the assets it harms
47
+ - A `MotivationDriver` (the threat) `triggers` it; a vulnerability `MotivationAssessment` `influences` it
48
+ MD
49
+
50
+ icon "bell-notification"
51
+ layer "application"
52
+
53
+ annotation "event/type",
54
+ description: "What kind of event this is (specialization of the event, see the risk and security overlay)",
55
+ enum: %w[threat-event attack loss-event incident opportunity-event audit scan change other],
56
+ filter: :word,
57
+ summary: true
58
+
59
+ annotation "event/severity",
60
+ description: "Severity of the event",
61
+ enum: %w[info low medium high critical],
62
+ filter: :word,
63
+ summary: true
64
+
65
+ annotation "event/occurred",
66
+ description: "When the event happened or is expected (ISO 8601 date or time)",
67
+ title: "Occurred",
68
+ validator: ->(value) { Archsight::Resources::Page.timestamp_error(value) }
69
+
70
+ relation :triggers, :applicationServices, :ApplicationService
71
+ relation :triggers, :applicationEvents, :ApplicationEvent
72
+ relation :triggers, :businessEvents, :BusinessEvent
73
+ relation :causedBy, :businessActors, :BusinessActor
74
+ relation :causedBy, :applicationComponents, :ApplicationComponent
75
+ relation :causedBy, :technologyNodes, :TechnologyNode
76
+ relation :affects, :applicationServices, :ApplicationService
77
+ relation :affects, :applicationComponents, :ApplicationComponent
78
+ relation :affects, :dataObjects, :DataObject
79
+ end
@@ -2,7 +2,7 @@
2
2
 
3
3
  # ApplicationService represents the high level application service that implements capabilities
4
4
  class Archsight::Resources::ApplicationService < Archsight::Resources::Base
5
- include_annotations :git, :architecture, :generated, :backup
5
+ include_annotations :git, :architecture, :generated, :backup, :asset, :risk
6
6
 
7
7
  description <<~MD
8
8
  Represents a high-level application service that implements business capabilities.
@@ -24,6 +24,11 @@ class Archsight::Resources::ApplicationService < Archsight::Resources::Base
24
24
  - Logical groupings of application components
25
25
  - Services exposed to business processes
26
26
  - APIs and their implementations as a cohesive unit
27
+
28
+ ## Security and risk modelling
29
+
30
+ A service is an asset at risk (`asset/*` profile, protection needs) that loss events `affects`, a trigger target
31
+ for `ApplicationEvent`s, and the place where requirements are realized and evidenced.
27
32
  MD
28
33
 
29
34
  icon "cube"