aspex scan init # writes a starter .aspex.yaml in the current directory
aspex scan looks for ./.aspex.yaml, then ~/.config/aspex/config.yaml. Pass --config <path> to use a specific file. Commit the project-local file so the whole team and CI share one policy.
# Accept a specific risk. Every entry needs a reason.# Add an expiry so accepted risks get re-reviewed instead of forgotten.ignore: - rule: MCP004 server: filesystem reason: "Intentionally scoped to ~/projects for the monorepo" expires: 2027-01-01 - rule: MCP026 server: "internal-*" # globs match server names reason: "Our internal servers expose many tools by design"# Your severity for a rule. "off" disables it entirely.severity: MCP021: critical # plaintext HTTP is never acceptable here MCP026: low# Default gate when --fail-on is not passed on the command line.fail_on: high
Rules:
reason is required. A policy file with an unexplained ignore is rejected.
server is optional. Omit it to ignore a rule everywhere; use a glob like internal-* for a group.
An expired ignore stops suppressing and prints a warning, so the finding comes back into view instead of being silently forgotten.
Severity overrides are applied before scoring and before the --fail-on gate. Your score and your CI result reflect your policy, not the defaults.
Suppressed findings are always listed at the end of the report and in --json output under suppressed, so a clean run is never mistaken for “nothing found”.Attack paths (AP001…AP006, see Capabilities and attack paths) are governed the same way: - rule: AP003 with a reason accepts a path, optionally scoped with server: to one of the servers on it. Baselines record paths too, so --baseline hides pre-existing compositions and only new ones fail the gate.
Turning on --fail-on high against 30 servers with 90 existing findings fails forever. A baseline snapshots what exists today so only new findings fail the gate, then you burn the baseline down at your own pace.
# Day one: snapshot the current stateaspex scan --save-baseline aspex-baseline.json# From then on: only new findings are shown and gatedaspex scan --baseline aspex-baseline.json --fail-on high
Commit aspex-baseline.json. Re-run --save-baseline after you fix things to shrink it. Findings are keyed by server and rule ID, so the same rule appearing on a new server is correctly treated as new.
Use --baseline for the transition and .aspex.yaml ignores for permanent, explained decisions. A baseline entry means “not yet”; an ignore entry means “we decided”.
aspex scan knows what a server can do. aspex trace knows what your agents did. --with-trace joins them:
aspex scan --with-trace # last 7 days of agent activityaspex scan --with-trace --trace-since 30d
◆ Observed activity last 7d, from aspex trace logs postgres CRITICAL 340 calls · 3 tools 12 flagged (critical) filesystem CRITICAL 88 calls · 6 tools github HIGH not seen memory clean 41 calls · 4 tools ▲ Prioritize - risky AND in active use: CRITICAL postgres 340 calls, tools: execute_sql, list_tables, describe_table CRITICAL filesystem 88 calls, tools: read_file, write_file, ...
A critical server that was never invoked is a latent risk: remove it or scope it down. The same server invoked 340 times last week, twelve of them tripping a trace rule, is the one to fix today. The Prioritize list is servers with a HIGH or CRITICAL static finding and observed calls in the window.--json output includes the per-server activity under activity.
- uses: aspex-security/aspex/.github/actions/aspex-scan-action@main with: fail-on: high# .aspex.yaml and aspex-baseline.json are read from the checked-out repo.
Aspex ships a corpus of known-malicious and known-benign MCP servers under testdata/corpus/. Every malicious fixture declares the rule IDs that must fire; every benign fixture (real, popular servers such as the official filesystem, GitHub, Slack, and fetch servers) declares the highest severity Aspex may report. CI runs both on every change, so a rule cannot regress detection or start crying wolf on a server people actually use. Contributing a fixture is the highest-signal way to improve Aspex: see CONTRIBUTING.md.
{"docsConfig":{"theme":"mint","$schema":"https://mintlify.com/docs.json","name":"Aspex","colors":{"primary":"#ec3013","light":"#ff9783","dark":"#ae1800"},"logo":{"light":"https://mintcdn.com/aspex/AsYxeTAcjauo5hC7/logo/light.svg?fit=max\u0026auto=format\u0026n=AsYxeTAcjauo5hC7\u0026q=85\u0026s=291ecea15a099f8047decc0604202c15","dark":"https://mintcdn.com/aspex/AsYxeTAcjauo5hC7/logo/dark.svg?fit=max\u0026auto=format\u0026n=AsYxeTAcjauo5hC7\u0026q=85\u0026s=cbccbbea1c0bc688e22550711e3590f0","href":"/introduction"},"favicon":"https://mintcdn.com/aspex/AsYxeTAcjauo5hC7/favicon.svg?fit=max\u0026auto=format\u0026n=AsYxeTAcjauo5hC7\u0026q=85\u0026s=a76f00414e8ed34f1441b09d2bfaa544","navbar":{"links":[{"href":"https://github.com/aspex-security/aspex","label":"GitHub"},{"href":"https://github.com/aspex-security/aspex/blob/main/CHANGELOG.md","label":"Changelog"}],"primary":{"type":"button","label":"Install","href":"/install"}},"footer":{"socials":{"github":"https://github.com/aspex-security/aspex"}},"fonts":{"family":"Archivo"},"styling":{"eyebrows":"section","codeblocks":"dark","latex":false},"navigation":{"pages":[]}},"deployment":{"deploymentMetadataValue":{"subdomain":"aspex","hasAudioNarration":false,"actualSubdomain":"aspex","customDomains":[],"gitSource":{"type":"github","owner":"aspex-security","repo":"docs","deployBranch":"main","contentDirectory":"","isPrivate":false,"mountPath":"","label":""},"entitlements":{"AI_CHAT":{"status":"DISABLED"}},"buildId":"6aa7ebb78a94481b048c0895","clientVersion":"0.0.4076","searchFilterCounts":[{"language":"default","tag":"Commands","count":13},{"language":"default","tag":"Concepts","count":4},{"language":"default","tag":"Guides","count":4},{"language":"default","tag":"Start","count":4},{"language":"default","tag":"Reference","count":4}]},"assistantConfig":{"enableAskAiButton":false,"enableStarterQuestions":false,"enableContextualStarterQuestions":false,"enableAskAiSearchBar":true},"basePath":"","hasChatPermissions":false,"hasWebMcpPermissions":false,"toggles":[{"name":"kill-isr","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"agent-mintlify-slack","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"agent-integrations-settings","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"rbac-expansion","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automations-pr-grouping","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"custom-prefix","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"analytics-v7","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"user-flows-analytics","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"no-publish-flow","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-onboarding","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"llms-txt-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"snapshot-serving-live","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"stripTemperatureMiddleware","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"support-platform-pylon-zendesk","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"snapshot-serving","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"instant-rollback","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"granular-notifications-server","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"granular-notifications","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automations-fable","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"fixed-ai-action-pricing","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automation-resolve-merge-conflict","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"scoped-publishing","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"mintql","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"page-level-analytics","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-version-history-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"billing-page-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"full-page-search","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workspace-projects","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"assistant-v5","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"fork-pr-previews","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"revalidation-jwt","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-sso-scim","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"hobby-abuse-scan","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"dashboard-inbox","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-signup","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"turbopuffer-dual-write","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-enabled","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"approve-review-flow","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-metadata","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"sso-setup-deadline-banner","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"turbopuffer-serve","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"live-agents","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"comment-mode","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false}],"googleFontsInlined":true},"customCss":[{"filePath":"style.css","content":":root{--aspex-ink: #201e1d;--aspex-ground: #f3f2f2;--aspex-surface: #eae9e9;--aspex-accent: #ec3013;--aspex-accent-deep: #ae1800;--aspex-divider: rgba(32, 30, 29, 0.4)}#content-area *,#sidebar *,#navbar *,#topbar *,.prose *{border-radius:0!important}html:not(.dark) body,html:not(.dark) #navbar,html:not(.dark) #sidebar{background:var(--aspex-ground)}html.dark{--aspex-ink: #f3f2f2;--aspex-ground: #201e1d;--aspex-surface: #2c2a29;--aspex-divider: rgba(243, 242, 242, 0.35)}#navbar,#topbar{border-bottom:2px solid var(--aspex-divider)!important}#sidebar{border-right:2px solid var(--aspex-divider)!important}.prose hr{height:2px;border:0;background:var(--aspex-divider)}.prose h1{font-weight:800;letter-spacing:-0.02em;line-height:1.08}.prose h2{font-weight:800;letter-spacing:-0.015em}.prose h3,.prose h4{font-weight:800}#sidebar h5,.eyebrow,[class*=\"eyebrow\"]{font-size:11px;letter-spacing:0.08em;text-transform:uppercase;font-weight:600}#sidebar a,#sidebar li a{border-left:2px solid transparent;padding-left:12px}#sidebar a[aria-current=\"page\"],#sidebar li.active>a{border-left-color:var(--aspex-accent)!important;background:transparent!important;color:var(--aspex-ink)!important;font-weight:600}#navbar a[href=\"/install\"],.prose a.button-primary{background:var(--aspex-accent)!important;color:var(--aspex-ground)!important;font-weight:800;justify-content:flex-start}#navbar a[href=\"/install\"]:hover{background:#dd2b0f!important}.prose pre,[class*=\"codeblock\"] pre{background:#201e1d!important;border-top:2px solid var(--aspex-accent)}.prose :not(pre)>code,[class*=\"card\"] code{background:var(--aspex-surface);color:var(--aspex-ink);padding:2px 6px;font-size:0.9em}.prose table th{font-size:11px;letter-spacing:0.08em;text-transform:uppercase;color:rgba(32, 30, 29, 0.6);border-bottom:2px solid var(--aspex-divider)}html.dark .prose table th{color:rgba(243, 242, 242, 0.6)}.prose table td{border-bottom:1px solid var(--aspex-divider)}.prose table tr:nth-child(2n) td{background:transparent}.prose .card,[class*=\"card\"]{border:2px solid var(--aspex-divider)!important;box-shadow:none!important}.prose .card:hover{background:var(--aspex-surface)}.callout,[class*=\"callout\"]{border-left:2px solid var(--aspex-accent)!important;background:transparent!important}[class*=\"step-indicator\"]{background:var(--aspex-ink)!important;color:var(--aspex-ground)!important;font-weight:800}:focus-visible{outline:2px solid var(--aspex-accent);outline-offset:2px}::selection{background:rgba(236, 48, 19, 0.3)}.prose a{color:var(--aspex-accent-deep);text-underline-offset:3px}html.dark .prose a{color:var(--aspex-light, #ff9783)}html.dark #sidebar a[aria-current=\"page\"],html.dark #sidebar li.active>a{color:var(--aspex-ink)!important}"}],"page":{"pagePath":"guides/policy","slug":"/guides/policy","pageMetadata":{"title":"Policy, baselines and prioritization","description":"Make aspex scan enforce your team's rules, adopt it on an estate with existing findings, and fix the risky servers that are actually in use first.","href":"/guides/policy"},"description":{"compiledSource":"\"use strict\";\nconst {jsx: _jsx} = arguments[0];\nconst {useMDXComponents: _provideComponents} = arguments[0];\nfunction _createMdxContent(props) {\n const _components = {\n p: \"p\",\n ..._provideComponents(),\n ...props.components\n };\n return _jsx(_components.p, {\n children: \"Make aspex scan enforce your team’s rules, adopt it on an estate with existing findings, and fix the risky servers that are actually in use first.\"\n });\n}\nfunction MDXContent(props = {}) {\n const {wrapper: MDXLayout} = {\n ..._provideComponents(),\n ...props.components\n };\n return MDXLayout ? _jsx(MDXLayout, {\n ...props,\n children: _jsx(_createMdxContent, {\n ...props\n })\n }) : _createMdxContent(props);\n}\nreturn {\n default: MDXContent\n};\n","frontmatter":{},"scope":{}},"pageType":"default","mdx":{"mdxSource":{"compiledSource":"\"use strict\";const{Fragment:_Fragment,jsx:_jsx,jsxs:_jsxs}=arguments[0];const{useMDXComponents:_provideComponents}=arguments[0];function _createMdxContent(props){const _components={a:`a`,code:`code`,li:`li`,p:`p`,pre:`pre`,span:`span`,strong:`strong`,tbody:`tbody`,td:`td`,th:`th`,thead:`thead`,tr:`tr`,ul:`ul`,..._provideComponents(),...props.components},{CodeBlock,Heading,Table,Tip}=_components;if(!CodeBlock)_missingMdxReference(`CodeBlock`,true);if(!Heading)_missingMdxReference(`Heading`,true);if(!Table)_missingMdxReference(`Table`,true);if(!Tip)_missingMdxReference(`Tip`,true);return _jsxs(_Fragment,{children:[_jsxs(_components.p,{children:[`Three features turn `,_jsx(_components.code,{children:`aspex scan`}),` from a scanner a developer runs into a control a security team owns.`]}),`\n`,_jsxs(Table,{children:[_jsx(_components.thead,{children:_jsxs(_components.tr,{children:[_jsx(_components.th,{children:`Problem`}),_jsx(_components.th,{children:`Feature`})]})}),_jsxs(_components.tbody,{children:[_jsxs(_components.tr,{children:[_jsx(_components.td,{children:`A finding you have consciously accepted keeps failing CI`}),_jsxs(_components.td,{children:[_jsxs(_components.strong,{children:[_jsx(_components.code,{children:`.aspex.yaml`}),` ignore`]}),` - accept a risk with a reason and an expiry`]})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:`The default severities are not your severities`}),_jsxs(_components.td,{children:[_jsxs(_components.strong,{children:[_jsx(_components.code,{children:`.aspex.yaml`}),` severity`]}),` - promote, demote, or disable any rule`]})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:`90 findings on day one, and you cannot fix them all before enabling the gate`}),_jsxs(_components.td,{children:[_jsx(_components.strong,{children:`Baseline`}),` - hide pre-existing findings, fail only on new ones`]})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:`30 risky servers, and you do not know which to fix first`}),_jsxs(_components.td,{children:[_jsx(_components.strong,{children:_jsx(_components.code,{children:`--with-trace`})}),` - rank by static risk x observed use`]})]})]})]}),`\n`,_jsxs(Heading,{level:`2`,id:`policy-file-aspex-yaml`,children:[`Policy file: `,_jsx(_components.code,{children:`.aspex.yaml`})]}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`1`,language:`shellscript`,children:_jsx(_components.pre,{className:`shiki shiki-themes dark-plus dark-plus`,style:{backgroundColor:`#0B0C0E`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#D4D4D4`,\"--shiki-dark\":`#D4D4D4`},language:`shellscript`,children:_jsxs(_components.code,{language:`shellscript`,numberOfLines:`1`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#DCDCAA`,\"--shiki-dark\":`#DCDCAA`},children:`aspex`}),_jsx(_components.span,{style:{color:`#CE9178`,\"--shiki-dark\":`#CE9178`},children:` scan`}),_jsx(_components.span,{style:{color:`#CE9178`,\"--shiki-dark\":`#CE9178`},children:` init`}),_jsx(_components.span,{style:{color:`#6A9955`,\"--shiki-dark\":`#6A9955`},children:` # writes a starter .aspex.yaml in the current directory`})]}),`\n`]})})}),`\n`,_jsxs(_components.p,{children:[_jsx(_components.code,{children:`aspex scan`}),` looks for `,_jsx(_components.code,{children:`./.aspex.yaml`}),`, then `,_jsx(_components.code,{children:`~/.config/aspex/config.yaml`}),`. Pass `,_jsx(_components.code,{children:`--config \u003cpath>`}),` to use a specific file. Commit the project-local file so the whole team and CI share one policy.`]}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`18`,language:`yaml`,children:_jsx(_components.pre,{className:`shiki shiki-themes dark-plus dark-plus`,style:{backgroundColor:`#0B0C0E`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#D4D4D4`,\"--shiki-dark\":`#D4D4D4`},language:`yaml`,children:_jsxs(_components.code,{language:`yaml`,numberOfLines:`18`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6A9955`,\"--shiki-dark\":`#6A9955`},children:`# Accept a specific risk. Every entry needs a reason.`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6A9955`,\"--shiki-dark\":`#6A9955`},children:`# Add an expiry so accepted risks get re-reviewed instead of forgotten.`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#569CD6`,\"--shiki-dark\":`#569CD6`},children:`ignore`}),_jsx(_components.span,{style:{color:`#D4D4D4`,\"--shiki-dark\":`#D4D4D4`},children:`:`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#D4D4D4`,\"--shiki-dark\":`#D4D4D4`},children:` - `}),_jsx(_components.span,{style:{color:`#569CD6`,\"--shiki-dark\":`#569CD6`},children:`rule`}),_jsx(_components.span,{style:{color:`#D4D4D4`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#CE9178`,\"--shiki-dark\":`#CE9178`},children:`MCP004`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#569CD6`,\"--shiki-dark\":`#569CD6`},children:` server`}),_jsx(_components.span,{style:{color:`#D4D4D4`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#CE9178`,\"--shiki-dark\":`#CE9178`},children:`filesystem`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#569CD6`,\"--shiki-dark\":`#569CD6`},children:` reason`}),_jsx(_components.span,{style:{color:`#D4D4D4`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#CE9178`,\"--shiki-dark\":`#CE9178`},children:`\"Intentionally scoped to ~/projects for the monorepo\"`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#569CD6`,\"--shiki-dark\":`#569CD6`},children:` expires`}),_jsx(_components.span,{style:{color:`#D4D4D4`,\"--shiki-dark\":`#D4D4D4`},children:`: 2027-01-01`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#D4D4D4`,\"--shiki-dark\":`#D4D4D4`},children:` - `}),_jsx(_components.span,{style:{color:`#569CD6`,\"--shiki-dark\":`#569CD6`},children:`rule`}),_jsx(_components.span,{style:{color:`#D4D4D4`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#CE9178`,\"--shiki-dark\":`#CE9178`},children:`MCP026`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#569CD6`,\"--shiki-dark\":`#569CD6`},children:` server`}),_jsx(_components.span,{style:{color:`#D4D4D4`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#CE9178`,\"--shiki-dark\":`#CE9178`},children:`\"internal-*\"`}),_jsx(_components.span,{style:{color:`#6A9955`,\"--shiki-dark\":`#6A9955`},children:` # globs match server names`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#569CD6`,\"--shiki-dark\":`#569CD6`},children:` reason`}),_jsx(_components.span,{style:{color:`#D4D4D4`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#CE9178`,\"--shiki-dark\":`#CE9178`},children:`\"Our internal servers expose many tools by design\"`})]}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6A9955`,\"--shiki-dark\":`#6A9955`},children:`# Your severity for a rule. \"off\" disables it entirely.`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#569CD6`,\"--shiki-dark\":`#569CD6`},children:`severity`}),_jsx(_components.span,{style:{color:`#D4D4D4`,\"--shiki-dark\":`#D4D4D4`},children:`:`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#569CD6`,\"--shiki-dark\":`#569CD6`},children:` MCP021`}),_jsx(_components.span,{style:{color:`#D4D4D4`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#CE9178`,\"--shiki-dark\":`#CE9178`},children:`critical`}),_jsx(_components.span,{style:{color:`#6A9955`,\"--shiki-dark\":`#6A9955`},children:` # plaintext HTTP is never acceptable here`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#569CD6`,\"--shiki-dark\":`#569CD6`},children:` MCP026`}),_jsx(_components.span,{style:{color:`#D4D4D4`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#CE9178`,\"--shiki-dark\":`#CE9178`},children:`low`})]}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6A9955`,\"--shiki-dark\":`#6A9955`},children:`# Default gate when --fail-on is not passed on the command line.`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#569CD6`,\"--shiki-dark\":`#569CD6`},children:`fail_on`}),_jsx(_components.span,{style:{color:`#D4D4D4`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#CE9178`,\"--shiki-dark\":`#CE9178`},children:`high`})]}),`\n`]})})}),`\n`,_jsx(_components.p,{children:`Rules:`}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[_jsx(_components.code,{children:`reason`}),` is required. A policy file with an unexplained ignore is rejected.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.code,{children:`server`}),` is optional. Omit it to ignore a rule everywhere; use a glob like `,_jsx(_components.code,{children:`internal-*`}),` for a group.`]}),`\n`,_jsx(_components.li,{children:`An expired ignore stops suppressing and prints a warning, so the finding comes back into view instead of being silently forgotten.`}),`\n`,_jsxs(_components.li,{children:[`Severity overrides are applied `,_jsx(_components.strong,{children:`before`}),` scoring and `,_jsx(_components.strong,{children:`before`}),` the `,_jsx(_components.code,{children:`--fail-on`}),` gate. Your score and your CI result reflect your policy, not the defaults.`]}),`\n`]}),`\n`,_jsxs(_components.p,{children:[`Suppressed findings are always listed at the end of the report and in `,_jsx(_components.code,{children:`--json`}),` output under `,_jsx(_components.code,{children:`suppressed`}),`, so a clean run is never mistaken for “nothing found”.`]}),`\n`,_jsxs(_components.p,{children:[`Attack paths (`,_jsx(_components.code,{children:`AP001`}),`…`,_jsx(_components.code,{children:`AP006`}),`, see `,_jsx(_components.a,{href:`/concepts/capabilities-and-attack-paths`,children:`Capabilities and attack paths`}),`) are governed the same way: `,_jsx(_components.code,{children:`- rule: AP003`}),` with a `,_jsx(_components.code,{children:`reason`}),` accepts a path, optionally scoped with `,_jsx(_components.code,{children:`server:`}),` to one of the servers on it. Baselines record paths too, so `,_jsx(_components.code,{children:`--baseline`}),` hides pre-existing compositions and only new ones fail the gate.`]}),`\n`,_jsx(Heading,{level:`2`,id:`baseline-adopt-on-an-existing-estate`,children:`Baseline: adopt on an existing estate`}),`\n`,_jsxs(_components.p,{children:[`Turning on `,_jsx(_components.code,{children:`--fail-on high`}),` against 30 servers with 90 existing findings fails forever. A baseline snapshots what exists today so only `,_jsx(_components.strong,{children:`new`}),` findings fail the gate, then you burn the baseline down at your own pace.`]}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`5`,language:`shellscript`,children:_jsx(_components.pre,{className:`shiki shiki-themes dark-plus dark-plus`,style:{backgroundColor:`#0B0C0E`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#D4D4D4`,\"--shiki-dark\":`#D4D4D4`},language:`shellscript`,children:_jsxs(_components.code,{language:`shellscript`,numberOfLines:`5`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6A9955`,\"--shiki-dark\":`#6A9955`},children:`# Day one: snapshot the current state`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#DCDCAA`,\"--shiki-dark\":`#DCDCAA`},children:`aspex`}),_jsx(_components.span,{style:{color:`#CE9178`,\"--shiki-dark\":`#CE9178`},children:` scan`}),_jsx(_components.span,{style:{color:`#569CD6`,\"--shiki-dark\":`#569CD6`},children:` --save-baseline`}),_jsx(_components.span,{style:{color:`#CE9178`,\"--shiki-dark\":`#CE9178`},children:` aspex-baseline.json`})]}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6A9955`,\"--shiki-dark\":`#6A9955`},children:`# From then on: only new findings are shown and gated`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#DCDCAA`,\"--shiki-dark\":`#DCDCAA`},children:`aspex`}),_jsx(_components.span,{style:{color:`#CE9178`,\"--shiki-dark\":`#CE9178`},children:` scan`}),_jsx(_components.span,{style:{color:`#569CD6`,\"--shiki-dark\":`#569CD6`},children:` --baseline`}),_jsx(_components.span,{style:{color:`#CE9178`,\"--shiki-dark\":`#CE9178`},children:` aspex-baseline.json`}),_jsx(_components.span,{style:{color:`#569CD6`,\"--shiki-dark\":`#569CD6`},children:` --fail-on`}),_jsx(_components.span,{style:{color:`#CE9178`,\"--shiki-dark\":`#CE9178`},children:` high`})]}),`\n`]})})}),`\n`,_jsxs(_components.p,{children:[`Commit `,_jsx(_components.code,{children:`aspex-baseline.json`}),`. Re-run `,_jsx(_components.code,{children:`--save-baseline`}),` after you fix things to shrink it. Findings are keyed by server and rule ID, so the same rule appearing on a new server is correctly treated as new.`]}),`\n`,_jsx(Tip,{children:_jsxs(_components.p,{children:[`Use `,_jsx(_components.code,{children:`--baseline`}),` for the transition and `,_jsx(_components.code,{children:`.aspex.yaml`}),` ignores for permanent, explained decisions. A baseline entry means “not yet”; an ignore entry means “we decided”.`]})}),`\n`,_jsxs(Heading,{level:`2`,id:`prioritize-with-with-trace`,children:[`Prioritize with `,_jsx(_components.code,{children:`--with-trace`})]}),`\n`,_jsxs(_components.p,{children:[_jsx(_components.code,{children:`aspex scan`}),` knows what a server `,_jsx(_components.strong,{children:`can`}),` do. `,_jsx(_components.code,{children:`aspex trace`}),` knows what your agents `,_jsx(_components.strong,{children:`did`}),`. `,_jsx(_components.code,{children:`--with-trace`}),` joins them:`]}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`2`,language:`shellscript`,children:_jsx(_components.pre,{className:`shiki shiki-themes dark-plus dark-plus`,style:{backgroundColor:`#0B0C0E`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#D4D4D4`,\"--shiki-dark\":`#D4D4D4`},language:`shellscript`,children:_jsxs(_components.code,{language:`shellscript`,numberOfLines:`2`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#DCDCAA`,\"--shiki-dark\":`#DCDCAA`},children:`aspex`}),_jsx(_components.span,{style:{color:`#CE9178`,\"--shiki-dark\":`#CE9178`},children:` scan`}),_jsx(_components.span,{style:{color:`#569CD6`,\"--shiki-dark\":`#569CD6`},children:` --with-trace`}),_jsx(_components.span,{style:{color:`#6A9955`,\"--shiki-dark\":`#6A9955`},children:` # last 7 days of agent activity`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#DCDCAA`,\"--shiki-dark\":`#DCDCAA`},children:`aspex`}),_jsx(_components.span,{style:{color:`#CE9178`,\"--shiki-dark\":`#CE9178`},children:` scan`}),_jsx(_components.span,{style:{color:`#569CD6`,\"--shiki-dark\":`#569CD6`},children:` --with-trace`}),_jsx(_components.span,{style:{color:`#569CD6`,\"--shiki-dark\":`#569CD6`},children:` --trace-since`}),_jsx(_components.span,{style:{color:`#CE9178`,\"--shiki-dark\":`#CE9178`},children:` 30d`})]}),`\n`]})})}),`\n`,_jsx(CodeBlock,{numberOfLines:`11`,language:`text`,children:_jsx(_components.pre,{className:`shiki shiki-themes dark-plus dark-plus`,style:{backgroundColor:`#0B0C0E`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#D4D4D4`,\"--shiki-dark\":`#D4D4D4`},language:`text`,children:_jsxs(_components.code,{language:`text`,numberOfLines:`11`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` ◆ Observed activity last 7d, from aspex trace logs`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` postgres CRITICAL 340 calls · 3 tools 12 flagged (critical)`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` filesystem CRITICAL 88 calls · 6 tools`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` github HIGH not seen`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` memory clean 41 calls · 4 tools`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` ▲ Prioritize - risky AND in active use:`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` CRITICAL postgres 340 calls, tools: execute_sql, list_tables, describe_table`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` CRITICAL filesystem 88 calls, tools: read_file, write_file, ...`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{})})]})})}),`\n`,_jsxs(_components.p,{children:[`A critical server that was never invoked is a latent risk: remove it or scope it down. The same server invoked 340 times last week, twelve of them tripping a trace rule, is the one to fix today. The `,_jsx(_components.code,{children:`Prioritize`}),` list is servers with a HIGH or CRITICAL static finding `,_jsx(_components.strong,{children:`and`}),` observed calls in the window.`]}),`\n`,_jsxs(_components.p,{children:[_jsx(_components.code,{children:`--json`}),` output includes the per-server activity under `,_jsx(_components.code,{children:`activity`}),`.`]}),`\n`,_jsx(Heading,{level:`2`,id:`ci-example`,children:`CI example`}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`4`,language:`yaml`,children:_jsx(_components.pre,{className:`shiki shiki-themes dark-plus dark-plus`,style:{backgroundColor:`#0B0C0E`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#D4D4D4`,\"--shiki-dark\":`#D4D4D4`},language:`yaml`,children:_jsxs(_components.code,{language:`yaml`,numberOfLines:`4`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#D4D4D4`,\"--shiki-dark\":`#D4D4D4`},children:`- `}),_jsx(_components.span,{style:{color:`#569CD6`,\"--shiki-dark\":`#569CD6`},children:`uses`}),_jsx(_components.span,{style:{color:`#D4D4D4`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#CE9178`,\"--shiki-dark\":`#CE9178`},children:`aspex-security/aspex/.github/actions/aspex-scan-action@main`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#569CD6`,\"--shiki-dark\":`#569CD6`},children:` with`}),_jsx(_components.span,{style:{color:`#D4D4D4`,\"--shiki-dark\":`#D4D4D4`},children:`:`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#569CD6`,\"--shiki-dark\":`#569CD6`},children:` fail-on`}),_jsx(_components.span,{style:{color:`#D4D4D4`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#CE9178`,\"--shiki-dark\":`#CE9178`},children:`high`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6A9955`,\"--shiki-dark\":`#6A9955`},children:`# .aspex.yaml and aspex-baseline.json are read from the checked-out repo.`})}),`\n`]})})}),`\n`,_jsx(Heading,{level:`2`,id:`detection-contract`,children:`Detection contract`}),`\n`,_jsxs(_components.p,{children:[`Aspex ships a corpus of known-malicious and known-benign MCP servers under `,_jsx(_components.code,{children:`testdata/corpus/`}),`. Every malicious fixture declares the rule IDs that must fire; every benign fixture (real, popular servers such as the official filesystem, GitHub, Slack, and fetch servers) declares the highest severity Aspex may report. CI runs both on every change, so a rule cannot regress detection or start crying wolf on a server people actually use. Contributing a fixture is the highest-signal way to improve Aspex: see `,_jsx(_components.a,{href:`https://github.com/aspex-security/aspex/blob/main/CONTRIBUTING.md`,children:`CONTRIBUTING.md`}),`.`]})]})}function MDXContent(props={}){const{wrapper:MDXLayout}={..._provideComponents(),...props.components};return MDXLayout?_jsx(MDXLayout,{...props,children:_jsx(_createMdxContent,{...props})}):_createMdxContent(props)}return{default:MDXContent};function _missingMdxReference(id,component){throw new Error(`Expected `+(component?`component`:`object`)+\" `\"+id+\"` to be defined: you likely forgot to import, pass, or provide it.\")}","frontmatter":{},"scope":{"codeStyling":"dark","config":{},"pageMetadata":{"title":"Policy, baselines and prioritization","description":"Make aspex scan enforce your team's rules, adopt it on an estate with existing findings, and fix the risky servers that are actually in use first.","href":"/guides/policy"}}},"mdxSourceWithNoJs":null},"mdxExtracts":{"tableOfContents":[{"title":"Policy file: .aspex.yaml","slug":"policy-file-aspex-yaml","depth":2,"children":[]},{"title":"Baseline: adopt on an existing estate","slug":"baseline-adopt-on-an-existing-estate","depth":2,"children":[]},{"title":"Prioritize with --with-trace","slug":"prioritize-with-with-trace","depth":2,"children":[]},{"title":"CI example","slug":"ci-example","depth":2,"children":[]},{"title":"Detection contract","slug":"detection-contract","depth":2,"children":[]}],"codeExamples":{}},"jsLinks":[],"subdomain":"aspex","siteName":"Aspex","title":"Policy, baselines and prioritization - Aspex","navMaps":{"firstHrefInVersion":{},"firstHrefInLanguage":{}},"lastModified":"2026-09-11T11:35:37.110Z","originalFileLocation":"guides/policy.mdx"},"headHtml":"\u003cscript data-mint-head>(function(){var d=document.documentElement,p=null;if(!p){try{p=localStorage.getItem(\"isDarkMode\")}catch(e){}if(p==='true')p='dark';else if(p==='false')p='light';if(p!=='light'\u0026\u0026p!=='dark'\u0026\u0026p!=='system')p=\"system\"}var r=p==='system'?(matchMedia(\"(prefers-color-scheme: dark)\").matches?'dark':'light'):p;d.classList.remove(r==='dark'?'light':'dark');d.classList.add(r);d.setAttribute(\"data-theme-preference\",p)})();\u003c/script>\u003cmeta data-mint-head name=\"description\" content=\"Make aspex scan enforce your team\u0026#x27;s rules, adopt it on an estate with existing findings, and fix the risky servers that are actually in use first.\">\u003cmeta data-mint-head name=\"application-name\" content=\"Aspex\">\u003cmeta data-mint-head name=\"generator\" content=\"Mintlify\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"192x192\" href=\"/mintlify-assets/_mintlify/favicons/aspex/QVudd8SD-Ga_PaCT/_generated/favicon/android-chrome-192x192.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"apple-touch-icon\" type=\"image/png\" sizes=\"180x180\" href=\"/mintlify-assets/_mintlify/favicons/aspex/QVudd8SD-Ga_PaCT/_generated/favicon/apple-touch-icon.png\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"/mintlify-assets/_mintlify/favicons/aspex/QVudd8SD-Ga_PaCT/_generated/favicon/favicon-16x16.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"/mintlify-assets/_mintlify/favicons/aspex/QVudd8SD-Ga_PaCT/_generated/favicon/favicon-32x32.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"shortcut icon\" type=\"image/x-icon\" href=\"/mintlify-assets/_mintlify/favicons/aspex/QVudd8SD-Ga_PaCT/_generated/favicon/favicon.ico\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"192x192\" href=\"/mintlify-assets/_mintlify/favicons/aspex/QVudd8SD-Ga_PaCT/_generated/favicon-dark/android-chrome-192x192.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"/mintlify-assets/_mintlify/favicons/aspex/QVudd8SD-Ga_PaCT/_generated/favicon-dark/favicon-16x16.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"/mintlify-assets/_mintlify/favicons/aspex/QVudd8SD-Ga_PaCT/_generated/favicon-dark/favicon-32x32.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"shortcut icon\" type=\"image/x-icon\" href=\"/mintlify-assets/_mintlify/favicons/aspex/QVudd8SD-Ga_PaCT/_generated/favicon-dark/favicon.ico\" media=\"(prefers-color-scheme: dark)\">\u003cmeta data-mint-head property=\"og:title\" content=\"Policy, baselines and prioritization - Aspex\">\u003cmeta data-mint-head property=\"og:description\" content=\"Make aspex scan enforce your team\u0026#x27;s rules, adopt it on an estate with existing findings, and fix the risky servers that are actually in use first.\">\u003cmeta data-mint-head property=\"og:site_name\" content=\"Aspex\">\u003cmeta data-mint-head property=\"og:url\" content=\"https://aspex.mintlify.app/guides/policy\">\u003cmeta data-mint-head property=\"og:type\" content=\"website\">\u003cmeta data-mint-head property=\"og:image\" content=\"https://aspex.mintlify.site/_mintlify/api/og/v2?division=Guides\u0026amp;title=Policy%2C+baselines+and+prioritization\u0026amp;description=Make+aspex+scan+enforce+your+team%27s+rules%2C+adopt+it+on+an+estate+with+existing+findings%2C+and+fix+the+risky+servers+that+are+actually+in+use+first.\u0026amp;theme=32228760862f899422b398a8\u0026amp;signature=4cb27085485699066822ddc37e4ae3d912a3b7de4fa7098fbe056e85348da610\">\u003cmeta data-mint-head property=\"og:image:width\" content=\"1200\">\u003cmeta data-mint-head property=\"og:image:height\" content=\"630\">\u003cmeta data-mint-head name=\"twitter:card\" content=\"summary_large_image\">\u003cmeta data-mint-head name=\"twitter:title\" content=\"Policy, baselines and prioritization - Aspex\">\u003cmeta data-mint-head name=\"twitter:description\" content=\"Make aspex scan enforce your team\u0026#x27;s rules, adopt it on an estate with existing findings, and fix the risky servers that are actually in use first.\">\u003cmeta data-mint-head name=\"twitter:image\" content=\"https://aspex.mintlify.site/_mintlify/api/og/v2?division=Guides\u0026amp;title=Policy%2C+baselines+and+prioritization\u0026amp;description=Make+aspex+scan+enforce+your+team%27s+rules%2C+adopt+it+on+an+estate+with+existing+findings%2C+and+fix+the+risky+servers+that+are+actually+in+use+first.\u0026amp;theme=32228760862f899422b398a8\u0026amp;signature=4cb27085485699066822ddc37e4ae3d912a3b7de4fa7098fbe056e85348da610\">\u003cmeta data-mint-head name=\"twitter:image:width\" content=\"1200\">\u003cmeta data-mint-head name=\"twitter:image:height\" content=\"630\">\u003cmeta data-mint-head name=\"msapplication-config\" content=\"/mintlify-assets/_mintlify/favicons/aspex/QVudd8SD-Ga_PaCT/_generated/favicon/browserconfig.xml\">\u003cmeta data-mint-head name=\"apple-mobile-web-app-title\" content=\"Aspex\">\u003cmeta data-mint-head name=\"msapplication-TileColor\" content=\"#ec3013\">\u003clink data-mint-head rel=\"canonical\" href=\"https://aspex.mintlify.app/guides/policy\">\u003clink data-mint-head rel=\"alternate\" type=\"application/xml\" href=\"/sitemap.xml\">\u003clink data-mint-head rel=\"alternate\" type=\"text/markdown\" href=\"/guides/policy.md\">\u003cscript data-mint-head type=\"application/ld+json\">{\"@context\":\"https://schema.org\",\"@graph\":[{\"@type\":\"Organization\",\"@id\":\"https://aspex.mintlify.app/#organization\",\"name\":\"Aspex\",\"url\":\"https://aspex.mintlify.app\",\"logo\":{\"@type\":\"ImageObject\",\"url\":\"https://mintcdn.com/aspex/AsYxeTAcjauo5hC7/logo/light.svg?fit=max\u0026auto=format\u0026n=AsYxeTAcjauo5hC7\u0026q=85\u0026s=291ecea15a099f8047decc0604202c15\"}},{\"@type\":\"WebSite\",\"@id\":\"https://aspex.mintlify.app#website\",\"name\":\"Aspex\",\"url\":\"https://aspex.mintlify.app\",\"publisher\":{\"@id\":\"https://aspex.mintlify.app/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https://aspex.mintlify.app/guides/policy#webpage\",\"url\":\"https://aspex.mintlify.app/guides/policy\",\"name\":\"Policy, baselines and prioritization\",\"description\":\"Make aspex scan enforce your team's rules, adopt it on an estate with existing findings, and fix the risky servers that are actually in use first.\",\"dateModified\":\"2026-09-11T11:35:37.110Z\",\"isPartOf\":{\"@id\":\"https://aspex.mintlify.app#website\"},\"breadcrumb\":{\"@id\":\"https://aspex.mintlify.app/guides/policy#breadcrumb\"}},{\"@type\":\"BreadcrumbList\",\"@id\":\"https://aspex.mintlify.app/guides/policy#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Guides\",\"item\":\"https://aspex.mintlify.app/guides/daily-workflow\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Policy, baselines and prioritization\",\"item\":\"https://aspex.mintlify.app/guides/policy\"}]},{\"@type\":[\"Article\",\"TechArticle\"],\"@id\":\"https://aspex.mintlify.app/guides/policy#article\",\"headline\":\"Policy, baselines and prioritization\",\"name\":\"Policy, baselines and prioritization\",\"description\":\"Make aspex scan enforce your team's rules, adopt it on an estate with existing findings, and fix the risky servers that are actually in use first.\",\"url\":\"https://aspex.mintlify.app/guides/policy\",\"mainEntityOfPage\":{\"@id\":\"https://aspex.mintlify.app/guides/policy#webpage\"},\"dateModified\":\"2026-09-11T11:35:37.110Z\",\"publisher\":{\"@id\":\"https://aspex.mintlify.app/#organization\"},\"isPartOf\":{\"@id\":\"https://aspex.mintlify.app#website\"}}]}\u003c/script>\u003cscript data-mint-head type=\"application/ld+json\">{\"@context\":\"https://schema.org\",\"@type\":\"WebSite\",\"name\":\"Aspex\",\"creator\":{\"@type\":\"Organization\",\"name\":\"Mintlify\",\"url\":\"https://mintlify.com\"}}\u003c/script>","siteName":"Aspex","nav":{"global":null,"groups":[{"group":"Start","pages":[{"title":"Know what your agents can do. Know what they actually did.","sidebarTitle":"Introduction","href":"/introduction"},{"title":"Quickstart","href":"/quickstart"},{"title":"Common workflows","href":"/guides/common-workflows"},{"title":"Install","href":"/install"}]},{"group":"Concepts","pages":[{"title":"How Aspex reasons","href":"/concepts/how-aspex-reasons"},{"title":"Capabilities and attack paths","href":"/concepts/capabilities-and-attack-paths"},{"title":"Observed vs inferred","href":"/concepts/observed-vs-inferred"},{"title":"Score and blast radius","href":"/concepts/score-and-blast-radius"}]},{"group":"Commands","pages":[{"title":"aspex (front door)","href":"/tools/launcher"},{"title":"aspex scan","href":"/tools/scan"},{"title":"scan subcommands","href":"/tools/scan-subcommands"},{"title":"aspex trace","href":"/tools/trace"},{"title":"aspex explain","href":"/tools/explain"},{"title":"aspex simulate","href":"/tools/simulate"},{"title":"lock, verify, diff","href":"/tools/change-detection"},{"title":"aspex explore","href":"/tools/explore"},{"title":"aspex tighten","href":"/tools/tighten"},{"title":"aspex bom","href":"/tools/bom"},{"title":"aspex mcp","href":"/tools/mcp"},{"title":"aspex doctor","href":"/tools/doctor"},{"title":"aspex-attack","href":"/tools/attack"}]},{"group":"Guides","pages":[{"title":"Daily Workflow","href":"/guides/daily-workflow"},{"title":"CI integration","description":"Fail the build when a config change introduces a risky MCP server. GitHub Actions, SARIF, baselines, and the pre-commit hook.","href":"/guides/ci-integration"},{"title":"Policy, baselines and prioritization","href":"/guides/policy"},{"title":"VS Code and Cursor","description":"aspex scan findings as editor diagnostics, plus the SARIF viewer and pre-commit hook routes that work today.","href":"/guides/vscode"}]},{"group":"Reference","pages":[{"title":"Rules","href":"/reference/rules"},{"title":"Supported Clients","href":"/reference/clients"},{"title":"Agent Security Corpus","href":"/reference/corpus"},{"title":"Privacy","href":"/privacy"}]}]},"basePath":"","title":"Policy, baselines and prioritization - Aspex","buildId":"dpl_8LJbrAiZvr1K98WQNZXCyY5AvT34","deploymentId":"dpl_8LJbrAiZvr1K98WQNZXCyY5AvT34","dynamics":[],"chunks":[]}