Skip to content

Commit 7f37957

Browse files
committed
chore: review fixes
1 parent 1e8aa5f commit 7f37957

32 files changed

Lines changed: 512 additions & 361 deletions

common/src/components/ArchitectureDiagram.tsx

Lines changed: 22 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React from 'react';
1+
import React, { useId } from 'react';
22
import BrowserOnly from '@docusaurus/BrowserOnly';
33
import Xarrow from 'react-xarrows';
44
import {
@@ -80,16 +80,16 @@ function BoxNode({ id, title, className = '', bodyClassName = '', border = 'soli
8080
);
8181
}
8282

83-
function K8SCRDsBox() {
83+
function K8SCRDsBox({ id }: { id: string }) {
8484
return (
85-
<div id="arch-k8s-crds" className="flex items-center gap-3 bg-blue-600 rounded-xl px-5 py-3 shadow-lg border-2 border-blue-400">
85+
<div id={id} className="flex items-center gap-3 bg-blue-600 rounded-xl px-5 py-3 shadow-lg border-2 border-blue-400">
8686
<K8S className="w-8 h-8 text-white" />
8787
<span className="text-white font-bold text-sm">K8S CRDs</span>
8888
</div>
8989
);
9090
}
9191

92-
function MissionControlBox() {
92+
function MissionControlBox({ id }: { id: string }) {
9393
const features = [
9494
{ Icon: CanaryCheckerWhite, label: 'Health Checks' },
9595
{ Icon: ConfigDbWhite, label: 'Unified Catalog' },
@@ -98,7 +98,7 @@ function MissionControlBox() {
9898
];
9999

100100
return (
101-
<div id="arch-missionControl" className="rounded-2xl overflow-hidden border-2 shadow-2xl"
101+
<div id={id} className="rounded-2xl overflow-hidden border-2 shadow-2xl"
102102
style={{ borderColor: '#007fdf', backgroundColor: '#f7fbfe' }}>
103103
<div className="px-6 py-3 text-center" style={{ backgroundColor: '#007fdf' }}>
104104
<div className="flex items-center justify-center gap-2">
@@ -129,16 +129,16 @@ function MissionControlBox() {
129129
);
130130
}
131131

132-
function MCPServerBox() {
132+
function MCPServerBox({ id }: { id: string }) {
133133
return (
134-
<div id="arch-mcp-server" className="flex items-center gap-3 bg-indigo-600 rounded-xl px-5 py-3 shadow-lg border-2 border-indigo-400">
134+
<div id={id} className="flex items-center gap-3 bg-indigo-600 rounded-xl px-5 py-3 shadow-lg border-2 border-indigo-400">
135135
<Mcp className="w-7 h-7 text-white fill-white" />
136136
<span className="text-white font-bold text-sm">MCP Server</span>
137137
</div>
138138
);
139139
}
140140

141-
function IntegrationsBox() {
141+
function IntegrationsBox({ id }: { id: string }) {
142142
const integrations = [
143143
{ Icon: Aws },
144144
{ Icon: Azure },
@@ -163,7 +163,7 @@ function IntegrationsBox() {
163163
];
164164

165165
return (
166-
<div id="arch-integrations">
166+
<div id={id}>
167167
<BoxNode
168168
title="40+ Integrations"
169169
className="bg-slate-500"
@@ -182,16 +182,19 @@ interface ArchitectureDiagramProps {
182182
}
183183

184184
function ArchitectureDiagramInner({ className }: ArchitectureDiagramProps) {
185+
const prefix = useId();
186+
const id = (name: string) => `${prefix}-${name}`;
187+
185188
return (
186189
<div className={`${className || ''} relative flex flex-col items-center gap-10 py-8`}>
187-
<K8SCRDsBox />
188-
<MissionControlBox />
189-
<MCPServerBox />
190-
<IntegrationsBox />
190+
<K8SCRDsBox id={id('k8s-crds')} />
191+
<MissionControlBox id={id('missionControl')} />
192+
<MCPServerBox id={id('mcp-server')} />
193+
<IntegrationsBox id={id('integrations')} />
191194

192195
<Xarrow
193-
start="arch-k8s-crds"
194-
end="arch-missionControl"
196+
start={id('k8s-crds')}
197+
end={id('missionControl')}
195198
color="#3b82f6"
196199
strokeWidth={3}
197200
startAnchor="bottom"
@@ -200,8 +203,8 @@ function ArchitectureDiagramInner({ className }: ArchitectureDiagramProps) {
200203
dashness={{ strokeLen: 10, nonStrokeLen: 5, animation: 1 }}
201204
/>
202205
<Xarrow
203-
start="arch-missionControl"
204-
end="arch-mcp-server"
206+
start={id('missionControl')}
207+
end={id('mcp-server')}
205208
color="#6366f1"
206209
strokeWidth={3}
207210
startAnchor="bottom"
@@ -210,8 +213,8 @@ function ArchitectureDiagramInner({ className }: ArchitectureDiagramProps) {
210213
dashness={{ strokeLen: 10, nonStrokeLen: 5, animation: 1 }}
211214
/>
212215
<Xarrow
213-
start="arch-mcp-server"
214-
end="arch-integrations"
216+
start={id('mcp-server')}
217+
end={id('integrations')}
215218
color="#6366f1"
216219
strokeWidth={3}
217220
startAnchor="bottom"

common/src/components/AuditDiagram.tsx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -306,6 +306,11 @@ function AuditDiagramInner({ className }: AuditDiagramProps) {
306306
path="straight"
307307
startAnchor="right" endAnchor="left"
308308
/>
309+
<Xarrow start={id('catalog')} end={id('views')}
310+
{...primaryArrowProps}
311+
path="straight"
312+
startAnchor="right" endAnchor="left"
313+
/>
309314
<Xarrow start={id('catalog')} end={id('alerts')}
310315
{...primaryArrowProps}
311316
path="straight"

common/src/components/AuditLogDiagrams.tsx

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -31,13 +31,6 @@ const primaryArrowProps = {
3131
dashness: { strokeLen: 10, nonStrokeLen: 5, animation: 1 },
3232
} as const;
3333

34-
const secondaryArrowProps = {
35-
color: COLORS.muted,
36-
strokeWidth: 2,
37-
headSize: 3,
38-
dashness: { strokeLen: 6, nonStrokeLen: 4, animation: 1 },
39-
} as const;
40-
4134
function NodePill({ children }: { children: React.ReactNode }) {
4235
return (
4336
<div className="text-[10px] rounded px-2 py-1 text-center" style={pillStyle}>

common/src/components/ComparisonBox.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { SlClose, SlCheck } from "react-icons/sl";
33

44
function Pros({ children }: { children: React.ReactNode }) {
55
return (
6-
<div className="rounded-lg bg-primary-300 p-4 pt-5 pb-6 text-black md:w-1/2" style={{ border: "1px solid #0c63db" }}>
6+
<div className="rounded-lg bg-primary-300 p-4 pt-5 pb-6 text-black md:w-1/2 border border-blue-700">
77
<div className="w-full justify-center flex mb-3">
88
<SlCheck size="36px" style={{ strokeWidth: "1px" }} color="#0c63db" />
99
</div>
@@ -17,7 +17,7 @@ function Pros({ children }: { children: React.ReactNode }) {
1717

1818
function Cons({ children }: { children: React.ReactNode }) {
1919
return (
20-
<div className="rounded-lg border p-4 pt-5 pb-6 md:w-1/2" style={{ border: "1px solid #cbd5e1" }}>
20+
<div className="rounded-lg p-4 pt-5 pb-6 md:w-1/2 border border-slate-300">
2121
<div className="w-full justify-center flex mb-3">
2222
<SlClose size="36px" color="#64748b" />
2323
</div>

common/src/components/EntityModelDiagram.tsx

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ const entities = {
9191
],
9292
},
9393
externalUser: {
94-
title: 'ExternalUser',
94+
title: 'User',
9595
fields: [
9696
{ name: 'id', type: 'uuid', pk: true },
9797
{ name: 'name', type: 'string' },
@@ -103,7 +103,7 @@ const entities = {
103103
],
104104
},
105105
externalGroup: {
106-
title: 'ExternalGroup',
106+
title: 'Group',
107107
fields: [
108108
{ name: 'id', type: 'uuid', pk: true },
109109
{ name: 'name', type: 'string' },
@@ -114,18 +114,20 @@ const entities = {
114114
],
115115
},
116116
externalRole: {
117-
title: 'ExternalRole',
117+
title: 'Role',
118118
fields: [
119119
{ name: 'id', type: 'uuid', pk: true },
120120
{ name: 'name', type: 'string' },
121121
{ name: 'account_id', type: 'string' },
122122
{ name: 'role_type', type: 'string' },
123+
{ name: 'description', type: 'string' },
124+
{ name: 'aliases', type: '[]string' },
123125
{ name: 'application_id', type: 'uuid', fk: true },
124126
{ name: 'scraper_id', type: 'uuid', fk: true },
125127
],
126128
},
127129
externalUserGroup: {
128-
title: 'ExternalUserGroup',
130+
title: 'UserGroup',
129131
fields: [
130132
{ name: 'external_user_id', type: 'uuid', pk: true, fk: true },
131133
{ name: 'external_group_id', type: 'uuid', pk: true, fk: true },
@@ -141,7 +143,9 @@ const entities = {
141143
{ name: 'external_role_id', type: 'uuid', fk: true },
142144
{ name: 'application_id', type: 'uuid', fk: true },
143145
{ name: 'scraper_id', type: 'uuid', fk: true },
146+
{ name: 'source', type: 'string' },
144147
{ name: 'last_reviewed_at', type: 'timestamp' },
148+
{ name: 'last_reviewed_by', type: 'uuid' },
145149
],
146150
},
147151
configAccessLog: {
@@ -150,6 +154,7 @@ const entities = {
150154
{ name: 'config_id', type: 'uuid', pk: true, fk: true },
151155
{ name: 'external_user_id', type: 'uuid', pk: true, fk: true },
152156
{ name: 'scraper_id', type: 'uuid', pk: true, fk: true },
157+
{ name: 'created_at', type: 'timestamp' },
153158
{ name: 'mfa', type: 'bool' },
154159
{ name: 'count', type: 'int' },
155160
{ name: 'properties', type: 'jsonb' },
@@ -173,14 +178,14 @@ function EntityModelDiagramInner({ className }: EntityModelDiagramProps) {
173178
<EntityBox id={id('configItem-box')} accent={COLORS.accent} {...entities.configItem} />
174179
</div>
175180

176-
{/* Row 2: ExternalUser — ConfigAccess (center) — ExternalRole */}
181+
{/* Row 2: User — ConfigAccess (center) — Role */}
177182
<div className="flex justify-center items-start gap-12 mb-12">
178183
<EntityBox id={id('externalUser-box')} {...entities.externalUser} />
179184
<EntityBox id={id('configAccess-box')} accent={COLORS.fk} {...entities.configAccess} />
180185
<EntityBox id={id('externalRole-box')} {...entities.externalRole} />
181186
</div>
182187

183-
{/* Row 3: ExternalUserGroupExternalGroup — ConfigAccessLog */}
188+
{/* Row 3: UserGroupGroup — ConfigAccessLog */}
184189
<div className="flex justify-center items-start gap-12">
185190
<EntityBox id={id('externalUserGroup-box')} accent={COLORS.muted} {...entities.externalUserGroup} />
186191
<EntityBox id={id('externalGroup-box')} {...entities.externalGroup} />
@@ -202,20 +207,20 @@ function EntityModelDiagramInner({ className }: EntityModelDiagramProps) {
202207
startAnchor={{ position: 'top', offset: { x: -20 } }}
203208
endAnchor="bottom"
204209
/>
205-
{/* ConfigAccess → ExternalUser */}
210+
{/* ConfigAccess → User */}
206211
<Xarrow start={id('configAccess-box')} end={id('externalUser-box')}
207212
{...arrowProps}
208213
path="straight"
209214
startAnchor="left" endAnchor="right"
210215
labels={{ middle: <RelLabel text="N:1" /> }}
211216
/>
212-
{/* ConfigAccess → ExternalRole */}
217+
{/* ConfigAccess → Role */}
213218
<Xarrow start={id('configAccess-box')} end={id('externalRole-box')}
214219
{...arrowProps}
215220
path="straight"
216221
startAnchor="right" endAnchor="left"
217222
/>
218-
{/* ConfigAccess → ExternalGroup */}
223+
{/* ConfigAccess → Group */}
219224
<Xarrow start={id('configAccess-box')} end={id('externalGroup-box')}
220225
{...arrowProps}
221226
path="straight"
@@ -228,28 +233,28 @@ function EntityModelDiagramInner({ className }: EntityModelDiagramProps) {
228233
startAnchor="right"
229234
endAnchor={{ position: 'right', offset: { y: 10 } }}
230235
/>
231-
{/* ConfigAccessLog → ExternalUser */}
236+
{/* ConfigAccessLog → User */}
232237
<Xarrow start={id('configAccessLog-box')} end={id('externalUser-box')}
233238
{...arrowProps}
234239
startAnchor={{ position: 'left', offset: { y: -10 } }}
235240
endAnchor={{ position: 'bottom', offset: { x: 20 } }}
236241
/>
237242

238-
{/* ExternalRole → Application */}
243+
{/* Role → Application */}
239244
<Xarrow start={id('externalRole-box')} end={id('application-box')}
240245
{...arrowProps}
241246
startAnchor="top" endAnchor="bottom"
242247
labels={{ middle: <RelLabel text="N:1" /> }}
243248
/>
244249

245-
{/* ExternalUserGroupExternalUser */}
250+
{/* UserGroupUser */}
246251
<Xarrow start={id('externalUserGroup-box')} end={id('externalUser-box')}
247252
{...arrowProps}
248253
path="straight"
249254
startAnchor="top" endAnchor="bottom"
250255
labels={{ middle: <RelLabel text="N:1" /> }}
251256
/>
252-
{/* ExternalUserGroupExternalGroup */}
257+
{/* UserGroupGroup */}
253258
<Xarrow start={id('externalUserGroup-box')} end={id('externalGroup-box')}
254259
{...arrowProps}
255260
path="straight"

mission-control/docs/guide/audit/access-logs.mdx

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ When `full` mode is enabled, the scraper expects each configuration item to pote
9696

9797
## Entra ID Audit Logs
9898

99-
Entra ID generates sign-in logs and directory audit logs that can be scraped as access logs. There are three approaches depending on your infrastructure and latency requirements:
99+
Entra ID generates sign-in logs and directory audit logs that Mission Control scrapes as access logs. There are three approaches depending on your infrastructure and latency requirements:
100100

101101
| | [HTTP + MS Graph](/docs/integrations/azure-ad/audit-logs/http-scraper) | [Logs Scraper](/docs/integrations/azure-ad/audit-logs/logs-scraper) | [Event Hub](/docs/integrations/azure-ad/audit-logs/event-hub) |
102102
|---|---|---|---|
@@ -113,6 +113,10 @@ For longer retention (beyond 30 days), export logs via Azure Monitor Diagnostic
113113

114114
## Example: Custom Scraper with Access Logs
115115

116+
:::note
117+
The `config_id` and `user_id` fields reference UUIDs in the database, but scrapers resolve them by matching on external identifiers (names, aliases, or scraper-assigned IDs). The example below uses human-readable strings to show the scraper input format — Mission Control resolves these to UUIDs internally.
118+
:::
119+
116120
```json title="config-with-access-logs.json"
117121
{
118122
"id": "db-prod-001",
@@ -124,7 +128,7 @@ For longer retention (beyond 30 days), export logs via Azure Monitor Diagnostic
124128
"access_logs": [
125129
{
126130
"config_id": "db-prod-001",
127-
"external_user_id": "user-123",
131+
"user": "user-123",
128132
"created_at": "2025-01-08T10:30:00Z",
129133
"mfa": true,
130134
"properties": {
@@ -134,7 +138,7 @@ For longer retention (beyond 30 days), export logs via Azure Monitor Diagnostic
134138
},
135139
{
136140
"config_id": "db-prod-001",
137-
"external_user_id": "user-456",
141+
"user": "user-456",
138142
"created_at": "2025-01-08T11:45:00Z",
139143
"mfa": false
140144
}

mission-control/docs/guide/audit/applications.mdx

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -86,13 +86,8 @@ spec:
8686
},
8787
{
8888
field: 'mapping',
89-
description: 'Maps the application to infrastructure, users, and environments',
89+
description: 'Maps the application to infrastructure, users, and environments (including custom view sections)',
9090
scheme: '[`Mapping`](#mapping)'
91-
},
92-
{
93-
field: 'sections',
94-
description: 'Custom view sections embedded in the application page',
95-
scheme: '`[]ViewSection`'
9691
}
9792
]}/>
9893

mission-control/docs/guide/audit/backups.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ Use [scraper transforms](/docs/guide/config-db/concepts/transform) to extract ba
6161
6262
## Backup Events from Changes
6363
64-
Track backup-related events by mapping [change types](/docs/guide/config-db/concepts/changes) in your scraper. CloudTrail events like `CreateDBSnapshot`, `DeleteDBSnapshot`, and `RestoreDBInstanceFromDBSnapshot` can be mapped to named change types for clearer audit reporting:
64+
Track backup-related events by mapping [change types](/docs/guide/config-db/concepts/changes) in your scraper. You can map CloudTrail events like `CreateDBSnapshot`, `DeleteDBSnapshot`, and `RestoreDBInstanceFromDBSnapshot` to named change types for clearer audit reporting:
6565

6666
```yaml title="backup-change-tracking.yaml"
6767
apiVersion: configs.flanksource.com/v1

mission-control/docs/guide/audit/change-tracking.mdx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@ Mission Control provides an immutable audit trail of all configuration modificat
1313

1414
Changes are recorded in two ways:
1515

16-
- **Diff changes**: Mission Control compares each scrape result with the previous version and records the diff automatically. No additional configuration is needed beyond setting up a scraper.
17-
- **Event-based changes**: External events (CloudTrail, Kubernetes events) are ingested as named change types, providing richer context about who made a change and why.
16+
- **Diff changes**: Mission Control compares each scrape result with the previous version and records the diff automatically. You don't need additional configuration beyond setting up a scraper.
17+
- **Event-based changes**: Mission Control ingests external events (CloudTrail, Kubernetes events) as named change types, providing richer context about who made a change and why.
1818

1919
See [Changes](/docs/guide/config-db/concepts/changes) for details on change types, severity mapping, and retention.
2020

mission-control/docs/guide/audit/concepts.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ Mission Control's audit system stores four categories of data: identities (who),
1515

1616
## How Entities Relate
1717

18-
**Identity providers** (Entra ID, AWS IAM, Kubernetes RBAC, databases) are scraped into **users**, **groups**, and **roles**. Users belong to groups, and roles define permission sets.
18+
Mission Control scrapes **identity providers** (Entra ID, AWS IAM, Kubernetes RBAC, databases) into **users**, **groups**, and **roles**. Users belong to groups, and roles define permission sets.
1919

2020
**Permissions** link users, groups, and roles to specific **resources** — the infrastructure items in your catalog (AWS accounts, Azure subscriptions, Kubernetes clusters, databases, etc.). This answers "who _can_ access what."
2121

0 commit comments

Comments
 (0)