From 2480443e30f336a485f0db90118030e0891e5323 Mon Sep 17 00:00:00 2001 From: danielmeppiel Date: Thu, 23 Apr 2026 01:29:00 +0200 Subject: [PATCH 1/4] docs(enterprise): refactor section IA -- hub + merge teams + dedupe governance The Enterprise section had 4 overlapping pages (Teams, Governance Guide, Governance & Compliance, apm-policy.yml) with duplicated narrative, sidebar order collisions, and an unclear path through the section for the three target personas (CISO, VP Eng, Platform Lead). Refactor to 7 pages with no overlap: 1. Enterprise (NEW hub) -- pillar paragraph + role router + map 2. Making the Case -- problem-at-scale (was Teams) + advocacy 3. Adoption Playbook -- phased rollout 4. Security Model -- supply-chain posture 5. Governance -- bypass contract + install gate (was Guide) 6. Policy Files -- mental model (was apm-policy.yml) 7. Policy Reference -- full schema Changes: - Add docs/src/content/docs/enterprise/index.md (hub page) - Merge teams.md narrative into making-the-case.md as the lead section ('The problem at scale' + 'How APM solves this'), then existing TL;DR / talking points / objections / RFC / comparison / ROI - Delete teams.md, governance.md (content grafted where appropriate) - Rename governance-guide.md title 'Governance Guide' -> 'Governance'; reorder - Rename apm-policy.md title 'apm-policy.yml' -> 'Policy Files'; reorder - Add redirects in astro.config.mjs so /enterprise/teams and /enterprise/governance resolve to their successors - Graft governance.md SOC 2 / security audit / change management scenarios into reference/lockfile-spec.md sec 9 (the lockfile-as-audit- trail home, where they belonged all along) - Update 4 inbound links (policy-reference, github-rulesets, ci-cd, ci-policy-setup) from .../enterprise/governance/ to .../enterprise/governance-guide/ Build passes, all internal links valid, 43 pages. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- docs/astro.config.mjs | 17 +- .../docs/enterprise/adoption-playbook.md | 2 +- .../src/content/docs/enterprise/apm-policy.md | 4 +- .../docs/enterprise/governance-guide.md | 4 +- .../src/content/docs/enterprise/governance.md | 240 ------------------ docs/src/content/docs/enterprise/index.md | 30 +++ .../docs/enterprise/making-the-case.md | 101 ++++++-- .../docs/enterprise/policy-reference.md | 4 +- docs/src/content/docs/enterprise/security.md | 2 +- docs/src/content/docs/enterprise/teams.md | 156 ------------ .../content/docs/guides/ci-policy-setup.md | 2 +- docs/src/content/docs/integrations/ci-cd.md | 2 +- .../docs/integrations/github-rulesets.md | 2 +- .../content/docs/reference/lockfile-spec.md | 44 ++++ 14 files changed, 175 insertions(+), 435 deletions(-) delete mode 100644 docs/src/content/docs/enterprise/governance.md create mode 100644 docs/src/content/docs/enterprise/index.md delete mode 100644 docs/src/content/docs/enterprise/teams.md diff --git a/docs/astro.config.mjs b/docs/astro.config.mjs index eb3c94bf1..895015367 100644 --- a/docs/astro.config.mjs +++ b/docs/astro.config.mjs @@ -9,6 +9,10 @@ import mermaid from 'astro-mermaid'; export default defineConfig({ site: 'https://microsoft.github.io', base: '/apm/', + redirects: { + '/enterprise/teams': '/enterprise/making-the-case', + '/enterprise/governance': '/enterprise/governance-guide', + }, integrations: [ mermaid(), starlight({ @@ -78,14 +82,13 @@ export default defineConfig({ { label: 'Enterprise', items: [ - { label: 'APM for Teams', slug: 'enterprise/teams' }, - { label: 'Governance Guide', slug: 'enterprise/governance-guide' }, - { label: 'Governance & Compliance', slug: 'enterprise/governance' }, - { label: 'apm-policy.yml', slug: 'enterprise/apm-policy' }, - { label: 'Policy Reference', slug: 'enterprise/policy-reference' }, - { label: 'Security Model', slug: 'enterprise/security' }, - { label: 'Adoption Playbook', slug: 'enterprise/adoption-playbook' }, + { label: 'Enterprise', slug: 'enterprise' }, { label: 'Making the Case', slug: 'enterprise/making-the-case' }, + { label: 'Adoption Playbook', slug: 'enterprise/adoption-playbook' }, + { label: 'Security Model', slug: 'enterprise/security' }, + { label: 'Governance', slug: 'enterprise/governance-guide' }, + { label: 'Policy Files', slug: 'enterprise/apm-policy' }, + { label: 'Policy Reference', slug: 'enterprise/policy-reference' }, ], }, { diff --git a/docs/src/content/docs/enterprise/adoption-playbook.md b/docs/src/content/docs/enterprise/adoption-playbook.md index 0d502617c..4d682d1e4 100644 --- a/docs/src/content/docs/enterprise/adoption-playbook.md +++ b/docs/src/content/docs/enterprise/adoption-playbook.md @@ -2,7 +2,7 @@ title: "Adoption Playbook" description: "A phased guide to rolling out APM from a pilot team to organization-wide adoption." sidebar: - order: 7 + order: 3 --- APM adoption follows a proven pattern: start small, prove value, expand. diff --git a/docs/src/content/docs/enterprise/apm-policy.md b/docs/src/content/docs/enterprise/apm-policy.md index b6debfb9c..52c294c1c 100644 --- a/docs/src/content/docs/enterprise/apm-policy.md +++ b/docs/src/content/docs/enterprise/apm-policy.md @@ -1,8 +1,8 @@ --- -title: "apm-policy.yml" +title: "Policy Files" description: "One org-wide policy file with tighten-only inheritance for AI agent dependencies, MCP servers, and compilation targets." sidebar: - order: 4 + order: 6 --- For the full enterprise rollout playbook and bypass contract, see the [Governance Guide](../governance-guide/). diff --git a/docs/src/content/docs/enterprise/governance-guide.md b/docs/src/content/docs/enterprise/governance-guide.md index cd5915e0c..4890af543 100644 --- a/docs/src/content/docs/enterprise/governance-guide.md +++ b/docs/src/content/docs/enterprise/governance-guide.md @@ -1,8 +1,8 @@ --- -title: Governance Guide +title: Governance description: How APM controls, governs, and enforces agent configuration -- with explicit guarantees, bypass surfaces, and known limitations. sidebar: - order: 2 + order: 5 --- :::note[Policy Engine Maturity] diff --git a/docs/src/content/docs/enterprise/governance.md b/docs/src/content/docs/enterprise/governance.md deleted file mode 100644 index a77290e0a..000000000 --- a/docs/src/content/docs/enterprise/governance.md +++ /dev/null @@ -1,240 +0,0 @@ ---- -title: "Governance & Compliance" -description: "Enforce AI agent configuration policies with lock files, audit trails, and CI gates." -sidebar: - order: 3 ---- - -For org-policy enforcement (apm-policy.yml, apm audit --ci, install gate), see the [Governance Guide](../governance-guide/). This page focuses on the lockfile audit trail and forensic recipes. - -:::caution[Experimental — Policy Engine] -Sections on this page covering organization policy enforcement (`apm audit --ci --policy`, `apm-policy.yml`, inheritance chains) describe an early preview feature for testing and feedback. Lock-file based governance (`apm audit --ci` baseline checks) is stable. The policy engine layer on top may change based on community input. -::: - -## The governance challenge - -**Twelve teams. Four agent stacks. One security review.** As AI agents become integral to software development, organizations face questions that traditional tooling was never designed to answer: - -- **Incident response.** What agent instructions were active during a production incident? -- **Change management.** Who approved this agent configuration change, and when? -- **Policy enforcement.** Are all teams using approved plugins and instruction sources? -- **Audit readiness.** Can we produce evidence of agent configuration state at any point in time? - -APM answers all four with two files: `apm.lock.yaml` records what was deployed; [`apm-policy.yml`](../apm-policy/) defines what is allowed. Both are git-tracked, both are reviewable, both reconstruct any historical state with one git command. - ---- - -## APM's governance pipeline - -Agent governance in APM follows a four-stage pipeline: - -``` -apm.yml (declare) -> apm.lock.yaml (pin) -> apm audit (verify) -> CI gate (enforce) -``` - -| Stage | Purpose | Artifact | -|-------|---------|----------| -| **Declare** | Define dependencies and their sources | `apm.yml` | -| **Pin** | Resolve every dependency to an exact commit | `apm.lock.yaml` | -| **Verify** | Scan deployed content for hidden threats | `apm audit` output | -| **Enforce** | Block merges when verification fails | Required status check | - -Each stage builds on the previous one. The lock file provides the audit trail, content scanning verifies file safety, and the CI gate prevents unapproved changes from reaching protected branches. - ---- - -## Lock file as audit trail - -The `apm.lock.yaml` file is the single source of truth for what agent configuration is deployed. Every dependency is pinned to an exact commit SHA, making the lock file a complete, point-in-time record of agent state. - -### What the lock file captures - -```yaml -lockfile_version: '1' -generated_at: '2025-03-11T18:13:45.123456+00:00' -apm_version: 0.25.0 -dependencies: - - repo_url: https://github.com/contoso/agent-standards.git - resolved_commit: a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0 - resolved_ref: main - version: 2.1.0 - depth: 1 - deployed_files: - - .github/agents/code-review.md - - .github/agents/security-scan.md - - repo_url: https://github.com/contoso/shared-skills.git - virtual_path: shared-skills/api-design - resolved_commit: f8e7d6c5b4a3f2e1d0c9b8a7f6e5d4c3b2a1f0e9 - resolved_ref: v1.4.0 - is_virtual: true - depth: 2 - resolved_by: contoso/agent-standards.git - deployed_files: - - .github/skills/api-design/ -``` - -Key fields for governance: - -- **`resolved_commit`**: Exact commit SHA. No ambiguity about what code was deployed. -- **`depth`**: `1` for direct dependencies, `2+` for transitive. Identifies supply chain depth. -- **`resolved_by`**: For transitive dependencies, traces which direct dependency introduced them. -- **`deployed_files`**: Explicit list of files placed in the repository. -- **`generated_at`** and **`apm_version`**: Metadata for forensic reconstruction. - -### Using git history for auditing - -Because `apm.lock.yaml` is a committed file, standard git operations answer governance questions directly: - -```bash -# Full history of every agent configuration change -git log --oneline apm.lock.yaml - -# Who changed agent config, and when -git log --format="%h %ai %an: %s" apm.lock.yaml - -# What was the exact agent configuration at release v4.2.1 -git show v4.2.1:apm.lock.yaml - -# Diff agent config between two releases -git diff v4.1.0..v4.2.1 -- apm.lock.yaml - -# Find the commit that introduced a specific dependency -git log -p --all -S 'contoso/agent-standards' -- apm.lock.yaml -``` - -No additional tooling is required. The lock file turns git into an agent configuration audit log. - ---- - -## Content scanning - -APM scans deployed files for hidden Unicode threats. `apm install` blocks critical findings automatically; `apm audit` provides reporting and remediation. See [Content scanning](../security/#content-scanning) in the security model for the threat model, severity levels, and usage details. - ---- - -## CI enforcement - -`apm install` is the CI gate — it blocks deployment of packages with critical content findings, exiting with code 1. No additional configuration is needed. - -`apm audit --ci` adds lockfile consistency checking (6 baseline checks, no configuration). Add `--policy org` to enforce organizational rules (16 additional policy checks). - -### Two-tier enforcement - -| Tier | Command | Checks | Requires policy | -|------|---------|--------|-----------------| -| Baseline | `apm audit --ci` | 6 lockfile consistency checks | No | -| Policy | `apm audit --ci --policy org` | 6 baseline + 16 policy checks | Yes | - -Baseline catches configuration drift. Policy enforces organizational standards. - -For step-by-step setup including SARIF integration and GitHub Code Scanning, see the [CI Policy Enforcement guide](../../guides/ci-policy-setup/). - ---- - -## Organization policy governance - -For organization-wide policy enforcement (`apm-policy.yml`, install gate, `apm audit --ci --policy org`, inheritance chains, the bypass contract, and the rollout playbook), see the [Governance Guide](../governance-guide/). The mental model for the policy file itself lives in [`apm-policy.yml`](../apm-policy/); the schema is in the [Policy Reference](../policy-reference/). - ---- - -## Drift detection - -:::note[Planned Feature] -`apm audit --drift` is not yet available. Currently, use `apm audit --ci --policy` with the `unmanaged_files` policy section to detect files in governance directories not tracked by APM. See the [Policy Reference](../policy-reference/#unmanaged_files) for configuration. -::: - ---- - -## Constitution injection - -A constitution is an organization-wide rules block applied to all compiled agent instructions. Define it in `memory/constitution.md` and APM injects it into every compilation output with hash verification: - -```markdown - -## Organization Standards - -- All code suggestions must include error handling. -- Never suggest credentials or secrets in code. -- Follow the organization's API design guidelines. -- Escalate security-sensitive operations to a human reviewer. -``` - -The constitution block is rendered into compiled output with a SHA-256 hash, enabling drift detection if the block is tampered with after compilation: - -```markdown - -hash: e3b0c44298fc1c14 path: memory/constitution.md -[Constitution content] - -``` - -This ensures that organizational rules are consistently applied across all teams and cannot be silently bypassed. - ---- - -## Integration with GitHub Rulesets - -GitHub Rulesets enforce APM governance at scale by configuring the APM workflow as a required status check across multiple repositories. For setup instructions, see the [GitHub Rulesets integration guide](../../integrations/github-rulesets/). - ---- - -## Compliance scenarios - -### SOC 2 evidence - -SOC 2 audits require evidence that configuration changes are authorized and traceable. APM's lock file provides this: - -- **Change authorization.** Every `apm.lock.yaml` change goes through a PR, requiring review and approval. -- **Change history.** `git log apm.lock.yaml` produces a complete, tamper-evident history of every agent configuration change with author, timestamp, and diff. -- **Point-in-time state.** `git show :apm.lock.yaml` reconstructs the exact agent configuration active at any release. - -Link auditors directly to the lock file history in your repository. No separate audit system is needed. - -### Security audit - -When a security review requires understanding what instructions agents were following: - -```bash -# What agent configuration was active at the time of the incident -git show :apm.lock.yaml - -# What files were deployed by a specific package -grep -A 10 'contoso/agent-standards' apm.lock.yaml - -# Full diff of agent config changes in the last 90 days -git log --since="90 days ago" -p -- apm.lock.yaml -``` - -The lock file answers "what was running" without requiring access to the original package repositories. The `resolved_commit` field points to the exact source code that was deployed. - -### Change management - -APM enforces change management by design: - -1. **Declaration.** Changes start in `apm.yml`, which is a committed, reviewable file. -2. **Resolution.** `apm install` resolves declarations to exact commits in `apm.lock.yaml`. -3. **Review.** Both files are included in the PR diff for peer review. -4. **Verification.** `apm audit --ci` verifies lockfile consistency. Add `--policy org` for organizational policy enforcement. -5. **Traceability.** Git history provides a permanent record of who changed what and when. - -No agent configuration change can reach a protected branch without passing through this pipeline. - ---- - -## Summary - -| Capability | Mechanism | Status | -|---|---|---| -| Dependency pinning | `apm.lock.yaml` with exact commit SHAs | Available | -| Audit trail | Git history of `apm.lock.yaml` | Available | -| Constitution injection | `memory/constitution.md` with hash verification | Available | -| Transitive MCP trust control | `--trust-transitive-mcp` flag | Available | -| Content scanning | Pre-deploy gate blocks critical hidden Unicode; `apm audit` for on-demand checks | Available | -| CI enforcement (content scanning) | Built into `apm install`; `apm audit` for SARIF reporting | Available | -| CI enforcement (lockfile consistency) | `apm audit --ci` for manifest/lockfile verification | Available | -| Organization policy enforcement | `apm audit --ci --policy org` with `apm-policy.yml` | Available | -| Policy inheritance | `extends:` for enterprise → org → repo chains | Available | -| Drift detection | `apm audit --drift` | Planned | -| GitHub Rulesets integration | Required status checks | Available | - -For CI/CD setup details, see the [CI/CD integration guide](../../integrations/ci-cd/). For policy schema and check details, see the [Policy Reference](../policy-reference/). For lock file internals, see [Key Concepts](../../introduction/key-concepts/). diff --git a/docs/src/content/docs/enterprise/index.md b/docs/src/content/docs/enterprise/index.md new file mode 100644 index 000000000..da5094f96 --- /dev/null +++ b/docs/src/content/docs/enterprise/index.md @@ -0,0 +1,30 @@ +--- +title: "Enterprise" +description: "APM for organizations: making the case, rolling out at scale, securing the agent supply chain, and governing dependencies by policy." +sidebar: + order: 1 +--- + +APM for organizations rests on three pillars: + +- **[Portable by manifest](../getting-started/quick-start/)** -- one `apm.yml` declares every dependency; `apm.lock.yaml` pins exact versions; every developer and every CI run gets the same agent setup. +- **[Secure by default](./security/)** -- `apm install` scans every package for hidden Unicode and other tampering before agents read it. Attack surface, scanners, and the MCP trust boundary are documented for procurement review. +- **[Governed by policy](./governance-guide/)** -- `apm-policy.yml` lets platform teams allow-list dependencies, restrict deploy targets, and enforce trust rules at install time across every repo, from a single source of truth. + +## Where to start + +| If you are... | Start here | +|---|---| +| A CISO or security reviewer | [Security Model](./security/) -> [Governance](./governance-guide/) | +| A VP of Engineering or Tech Lead evaluating APM | [Governance](./governance-guide/) -> [Adoption Playbook](./adoption-playbook/) | +| A champion building an internal pitch | [Making the Case](./making-the-case/) -> [Adoption Playbook](./adoption-playbook/) | +| An engineer authoring policy | [Policy Files](./apm-policy/) -> [Policy Reference](./policy-reference/) | + +## Section map + +- [Making the Case](./making-the-case/) -- problem-at-scale narrative, talking points by audience, objection handling, sample RFC, ROI framework. +- [Adoption Playbook](./adoption-playbook/) -- phased rollout from pilot team to organization-wide, with milestones, success metrics, and rollback options. +- [Security Model](./security/) -- supply-chain posture: pre-deploy gate, content scanners, hidden-Unicode threat model, MCP trust boundary. Consumed verbatim by procurement and security reviewers. +- [Governance](./governance-guide/) -- the flagship trust contract: bypass surfaces, install-gate guarantees, audit-log schema, rollout playbook, known gaps. Read this if you are deciding whether to make `apm audit --ci` a required check. +- [Policy Files](./apm-policy/) -- conceptual model of `apm-policy.yml`: what it is, what it declares, how to start one. +- [Policy Reference](./policy-reference/) -- complete schema for every `apm-policy.yml` field. diff --git a/docs/src/content/docs/enterprise/making-the-case.md b/docs/src/content/docs/enterprise/making-the-case.md index 93191af3e..ae349c5d1 100644 --- a/docs/src/content/docs/enterprise/making-the-case.md +++ b/docs/src/content/docs/enterprise/making-the-case.md @@ -1,18 +1,75 @@ --- title: "Making the Case" -description: "Talking points, objection handling, and resources for advocating APM adoption within your organization." +description: "Problem-at-scale narrative, talking points, objection handling, sample RFC, and ROI framework for advocating APM adoption within your organization." sidebar: - order: 8 + order: 2 --- -An internal advocacy toolkit for APM. Each section is self-contained and designed to be copied into RFCs, Slack messages, and proposals. +An internal advocacy toolkit. The lead section frames the problem; the rest is designed to be lifted directly into RFCs, Slack messages, leadership decks, and proposals. + +--- + +## The problem at scale + +Consider a mid-to-large engineering organization: 50 repositories, 200 developers, four AI coding tools (Copilot, Claude, Cursor, OpenCode). + +Without centralized configuration management, a predictable set of problems emerges: + +- **Manual configuration per repo.** Each team sets up agent configuration independently. Conventions diverge. Knowledge silos form. The "right" way to configure an agent depends on who you ask. +- **No audit trail.** When security or compliance asks "what agent configuration was active at release 4.2.1?" -- there is no answer. Configuration files were hand-edited, and no one tracked which version of which plugin was in use. +- **Version drift.** Developer A has v1.2 of a rules plugin. Developer B has v1.4. CI has whatever was last committed. Bugs that only reproduce under specific configurations become difficult to trace. +- **Onboarding friction.** A new developer reads the README, runs N install commands, copies configuration from a colleague's machine, and hopes nothing was missed. The gap between "environment works" and "environment matches the team standard" is invisible. +- **Ungoverned dependencies.** No platform-level control over which plugins, prompts, or MCP servers reach developer workstations -- the same problem regulated industries spent a decade solving for application code, now back in a new form. + +These are not hypothetical problems. They are the direct consequence of treating AI agent configuration as a manual, per-developer responsibility rather than as a managed dependency. + +## How APM solves this + +APM applies the same model that package managers brought to application dependencies -- declare, lock, install, audit -- to AI agent configuration. + +### Declare + +A single `apm.yml` file in the repository root declares all agent configuration dependencies: + +```yaml +dependencies: + apm: + - anthropics/skills/skills/frontend-design + - microsoft/apm-sample-package#v1.0.0 + - github/awesome-copilot/plugins/context-engineering + mcp: + - name: io.github.github/github-mcp-server + transport: http +``` + +This file is version-controlled, reviewed in pull requests, and readable by anyone on the team. + +### Lock + +Running `apm install` resolves every dependency and writes `apm.lock.yaml`, which pins the exact commit of every dependency. The lock file is committed to the repository. Two developers running `apm install` from the same lock file get identical configuration. A CI pipeline running `apm install` gets the same result as a developer workstation. + +### Install + +`apm install` reads the lock file and deploys configuration into the native formats expected by each tool -- `.github/` for Copilot, `.claude/` for Claude, `.cursor/` for Cursor, `.opencode/` for OpenCode. APM generates static files and then gets out of the way. There is no runtime, no daemon, no background process. + +### Audit + +Because `apm.lock.yaml` is a committed file, standard git tooling answers governance questions directly: + +- **What changed?** `git diff apm.lock.yaml` +- **When did it change?** `git log apm.lock.yaml` +- **What was active at a specific release?** `git show v4.2.1:apm.lock.yaml` +- **Is this environment current?** `apm audit` + +For the full forensic and compliance recipes, see the [Lock File Specification](../../reference/lockfile-spec/#9-auditing-patterns). --- ## TL;DR for Leadership -- **APM is an open-source dependency manager for AI agent configuration** — like package.json but for AI tools. It declares what your agents need in one manifest and installs it with one command. +- **APM is an open-source dependency manager for AI agent configuration** -- like `package.json` but for AI tools. It declares what your agents need in one manifest and installs it with one command. - **One manifest, one command, locked versions.** Every developer gets identical agent setup, every CI run is reproducible. No more configuration drift across teams. +- **Secure by default and governable.** Hidden-Unicode and content scanners run before any package reaches an agent; `apm-policy.yml` lets a platform team allow-list dependencies, restrict deploy targets, and enforce trust rules across every repo. See [Security Model](../security/) and [Governance](../governance-guide/). - **Zero lock-in.** APM generates native config files (`.github/`, `.claude/`, `AGENTS.md`). Remove APM and everything still works. --- @@ -29,13 +86,14 @@ An internal advocacy toolkit for APM. Each section is self-contained and designe - **Lock file integrity.** `apm.lock.yaml` pins exact versions and commit SHAs for every dependency. No silent updates, no supply chain surprises. - **Dependency provenance.** Every package resolves to a specific git repository and commit. The full dependency tree is inspectable before installation. -- **No code execution, no runtime.** APM is a dev-time tool only. It copies configuration files — it does not execute code, run background processes, or modify your application at runtime. +- **No code execution, no runtime.** APM is a dev-time tool only. It copies configuration files -- it does not execute code, run background processes, or modify your application at runtime. +- **Org-wide policy enforcement.** `apm-policy.yml` allow-lists dependency repos, restricts MCP transports and deploy targets, and is auto-discovered from the org's `.github` repo. See [Governance](../governance-guide/) for the bypass contract and install-gate guarantees. - **Full audit trail.** All configuration changes are committed to git. Compliance teams can review agent setup changes through standard code review processes. ### For Platform Teams - **Standardize AI configuration across N repos.** Publish a shared APM package with your organization's coding standards, approved MCP servers, and prompt templates. Every repo that depends on it stays in sync. -- **Enforce standards via CI gates.** `apm install` blocks packages with critical hidden-character findings — no configuration needed. `apm audit --ci` verifies lockfile consistency. Add `--policy org` for [organizational policy enforcement](../governance/#organization-policy-governance). +- **Enforce standards via CI gates.** `apm install` blocks packages with critical hidden-character findings -- no configuration needed. `apm audit --ci` verifies lockfile consistency. Add `--policy org` for [organizational policy enforcement](../governance-guide/). - **Version-controlled standards updates.** When standards change, update the shared package and bump the version. Teams adopt updates through normal dependency management, not ad-hoc communication. ### For Individual Developers @@ -54,7 +112,7 @@ Plugins handle single-tool installation for a single AI platform. APM adds capab - **Cross-tool composition.** One manifest manages configuration for Copilot, Claude, Cursor, OpenCode, and any other agent runtime simultaneously. - **Consumer-side lock files.** Plugins install the latest version. APM pins exact versions so your team stays synchronized. -- **CI enforcement.** Content scanning is built into `apm install` — no plugin equivalent exists. `apm audit --ci` adds lockfile consistency checks and `--policy org` enforces organizational rules. +- **CI enforcement.** Content scanning is built into `apm install` -- no plugin equivalent exists. `apm audit --ci` adds lockfile consistency checks and `--policy org` enforces organizational rules. - **Multi-source dependency resolution.** APM resolves transitive dependencies across packages from multiple git hosts. - **Shared organizational packages.** Plugins are published by tool vendors. APM packages are published by your own teams, containing your own standards and configurations. @@ -68,7 +126,7 @@ APM is a dev-time tool with zero runtime footprint. The workflow is: 2. Get configuration files. 3. Done. -There is no daemon, no background process, no runtime dependency. It is analogous to running `npm install` — you do not "maintain" npm at runtime. APM runs during setup and CI, then gets out of the way. +There is no daemon, no background process, no runtime dependency. It is analogous to running `npm install` -- you do not "maintain" npm at runtime. APM runs during setup and CI, then gets out of the way. Installation is a single binary with no system dependencies. Updates are a binary swap. The total operational surface is: one CLI binary, one manifest file, one lock file. @@ -113,15 +171,15 @@ This is a deliberate design choice. APM adds value on top of native formats rath ## Sample RFC Paragraph -The following is ready to copy into an internal proposal or RFC: +Ready to copy into an internal proposal: -> We propose adopting APM (Agent Package Manager) to manage AI agent configuration across our repositories. APM is an open-source, dev-time tool that provides a declarative manifest (`apm.yml`) and lock file (`apm.lock.yaml`) for AI coding agent setup — instructions, prompts, skills, plugins, and MCP servers. It resolves dependencies, generates native configuration files for each AI platform, and produces reproducible installs from locked versions. APM has zero runtime footprint: it runs during setup and CI, outputs standard config files, and introduces no vendor lock-in. Adopting APM will eliminate manual agent setup for new developers, enforce consistent configuration across teams, and provide an auditable record of all agent configuration changes through git history. The tool is MIT-licensed, maintained under the Microsoft GitHub organization, and supports GitHub, GitLab, Bitbucket, and Azure DevOps as package sources. +> We propose adopting APM (Agent Package Manager) to manage AI agent configuration across our repositories. APM is an open-source, dev-time tool that provides a declarative manifest (`apm.yml`) and lock file (`apm.lock.yaml`) for AI coding agent setup -- instructions, prompts, skills, plugins, and MCP servers. It resolves dependencies, generates native configuration files for each AI platform, and produces reproducible installs from locked versions. APM has zero runtime footprint: it runs during setup and CI, outputs standard config files, and introduces no vendor lock-in. Adopting APM will eliminate manual agent setup for new developers, enforce consistent configuration across teams, and provide an auditable record of all agent configuration changes through git history. Pre-deploy content scanning and an org-wide `apm-policy.yml` give the security and platform teams the controls they need to govern what reaches developer workstations. The tool is MIT-licensed, maintained under the Microsoft GitHub organization, and supports GitHub, GitLab, Bitbucket, and Azure DevOps as package sources. --- ## Quick Comparison -For stakeholders familiar with existing tools, this comparison clarifies where APM fits. +For stakeholders familiar with existing tools: | Capability | Manual Setup | Single-Tool Plugin | APM | |------------|-------------|-------------------|-----| @@ -130,6 +188,7 @@ For stakeholders familiar with existing tools, this comparison clarifies where A | Cross-tool support | N separate processes | Single tool only | Unified manifest | | Dependency resolution | Manual | None | Automatic, transitive | | CI enforcement | Custom scripts | Not available | Built into `apm install`; `apm audit --ci` for lockfile + policy checks | +| Org policy enforcement | Wiki pages, hope | Not available | `apm-policy.yml`, allow-lists, install-time gate | | Shared org standards | Wiki pages, copy-paste | Not available | Versioned packages | | Audit trail | Implicit via git | Varies by vendor | Explicit via `apm.lock.yaml` | | Lock-in | To manual process | To specific vendor | None (native output files) | @@ -138,8 +197,6 @@ For stakeholders familiar with existing tools, this comparison clarifies where A ## ROI Framework -Use these categories to estimate return on investment for your organization. - ### Time Saved | Factor | Estimate | @@ -152,7 +209,7 @@ Use these categories to estimate return on investment for your organization. With APM, setup reduces to `apm install` (under 30 seconds). Standards updates reduce to a version bump in `apm.yml` and a single `apm install`. -**Example calculation.** A team of 20 developers, each setting up 2 new repos per quarter, spending 30 minutes on manual agent configuration per repo: 20 hours per quarter in setup time alone. With APM, that drops to under 20 minutes total. +**Example.** A team of 20 developers, each setting up 2 new repos per quarter, spending 30 minutes on manual agent configuration per repo: 20 hours per quarter in setup time alone. With APM, that drops to under 20 minutes total. ### Risk Reduced @@ -162,7 +219,8 @@ With APM, setup reduces to `apm install` (under 30 seconds). Standards updates r | Configuration divergence across repos | Shared packages enforce a single source of truth | | Compliance audit gaps | Git history provides full change trail for every config change | | Unreviewed agent configuration changes | CI gates catch drift before merge | -| Supply chain concerns | Dependency provenance traced to specific git commits | +| Supply chain concerns | Dependency provenance traced to specific git commits; pre-deploy content scanners | +| Ungoverned dependency proliferation | `apm-policy.yml` allow-lists what every repo can install | ### Consistency Gains @@ -181,13 +239,13 @@ With APM, setup reduces to `apm install` (under 30 seconds). Standards updates r | Topic | Link | |-------|------| | Quick Start | [Installation](../../getting-started/installation/) | -| APM for Teams | [Team workflows and shared packages](../teams/) | -| CI/CD Integration | [Pipeline setup and enforcement](../../integrations/ci-cd/) | | Adoption Playbook | [Phased rollout guide](../adoption-playbook/) | +| Governance | [Bypass contract and install gate](../governance-guide/) | +| Security Model | [Supply-chain posture](../security/) | +| CI/CD Integration | [Pipeline setup and enforcement](../../integrations/ci-cd/) | | Why APM | [Problem statement and design principles](../../introduction/why-apm/) | | How It Works | [Architecture and compilation pipeline](../../introduction/how-it-works/) | | Manifest Schema | [apm.yml reference](../../reference/manifest-schema/) | -| Key Concepts | [Primitives, packages, and compilation](../../introduction/key-concepts/) | | Org-Wide Packages | [Publishing shared configuration](../../guides/org-packages/) | --- @@ -195,6 +253,7 @@ With APM, setup reduces to `apm install` (under 30 seconds). Standards updates r ## Next Steps 1. Review the [Adoption Playbook](../adoption-playbook/) for a phased rollout plan. -2. Start with a single team or repository as a pilot. -3. Publish a shared package with your organization's standards using the [APM for Teams](../teams/) guide. -4. Add APM to CI and measure adoption over 30 days. +2. Read [Governance](../governance-guide/) end-to-end before making `apm audit --ci` a required check. +3. Start with a single team or repository as a pilot. +4. Publish a shared package with your organization's standards using the [Org-Wide Packages guide](../../guides/org-packages/). +5. Add APM to CI and measure adoption over 30 days. diff --git a/docs/src/content/docs/enterprise/policy-reference.md b/docs/src/content/docs/enterprise/policy-reference.md index 9de8c81d9..9f373c044 100644 --- a/docs/src/content/docs/enterprise/policy-reference.md +++ b/docs/src/content/docs/enterprise/policy-reference.md @@ -1,7 +1,7 @@ --- title: Policy Reference sidebar: - order: 5 + order: 7 --- :::caution[Experimental Feature] @@ -871,6 +871,6 @@ manifest: ## Related -- [Governance & Compliance](../../enterprise/governance/) -- conceptual overview of APM's governance model +- [Governance](../../enterprise/governance-guide/) -- conceptual overview, bypass contract, and rollout playbook - [CI Policy Enforcement](../../guides/ci-policy-setup/) -- step-by-step CI setup tutorial - [GitHub Rulesets](../../integrations/github-rulesets/) -- enforce policy as a required status check diff --git a/docs/src/content/docs/enterprise/security.md b/docs/src/content/docs/enterprise/security.md index 453684a2a..719deeecc 100644 --- a/docs/src/content/docs/enterprise/security.md +++ b/docs/src/content/docs/enterprise/security.md @@ -2,7 +2,7 @@ title: "Security Model" description: "How APM handles supply chain security for AI agents — attack surface boundaries, content scanning, dependency provenance, path safety, and MCP trust." sidebar: - order: 6 + order: 4 --- This page documents APM's security posture for enterprise security reviews, compliance audits, and supply chain assessments. diff --git a/docs/src/content/docs/enterprise/teams.md b/docs/src/content/docs/enterprise/teams.md deleted file mode 100644 index b8eb5e40a..000000000 --- a/docs/src/content/docs/enterprise/teams.md +++ /dev/null @@ -1,156 +0,0 @@ ---- -title: "APM for Teams" -description: "How APM provides reproducibility, governance, and consistency for AI agent configuration at scale." -sidebar: - order: 1 ---- - -APM is an open-source dependency manager for AI agent configuration. -One manifest (`apm.yml`), one command (`apm install`), locked versions (`apm.lock.yaml`). -Every developer gets the same agent setup. -Every CI run is reproducible. -Every configuration change is auditable. - -## The problem at scale - -Consider a mid-to-large engineering organization: 50 repositories, 200 developers, four AI coding tools (Copilot, Claude, Cursor, OpenCode). - -Without centralized configuration management, a predictable set of problems emerges: - -- **Manual configuration per repo.** Each team sets up agent configuration independently. Conventions diverge. Knowledge silos form. The "right" way to configure an agent depends on who you ask. -- **No audit trail.** When security or compliance asks "what agent configuration was active at release 4.2.1?" — there is no answer. Configuration files were hand-edited, and no one tracked which version of which plugin was in use. -- **Version drift.** Developer A has v1.2 of a rules plugin. Developer B has v1.4. CI has whatever was last committed. Bugs that only reproduce under specific configurations become difficult to trace. -- **Onboarding friction.** A new developer reads the README, runs N install commands, copies configuration from a colleague's machine, and hopes nothing was missed. The gap between "environment works" and "environment matches the team standard" is invisible. - -These are not hypothetical problems. They are the direct consequence of treating AI agent configuration as a manual, per-developer responsibility rather than as a managed dependency. - -## How APM solves this - -APM applies the same model that package managers brought to application dependencies — declare, lock, install, audit — to AI agent configuration. - -### Declare - -A single `apm.yml` file in the repository root declares all agent configuration dependencies: - -```yaml -packages: - - name: org-security-rules - source: github:your-org/apm-packages - version: "^2.0" - - name: team-coding-standards - source: github:your-org/team-packages - version: "~1.3" - - name: project-context - source: ./local-packages/context -``` - -This file is version-controlled, reviewed in pull requests, and readable by anyone on the team. - -### Lock - -Running `apm install` resolves versions and writes `apm.lock.yaml`, which pins the exact version of every dependency. The lock file is committed to the repository. - -``` -# apm.lock.yaml (auto-generated) -org-security-rules==2.1.0 -team-coding-standards==1.3.4 -project-context==local -``` - -Two developers running `apm install` from the same lock file get identical configuration. A CI pipeline running `apm install` gets the same result as a developer workstation. - -### Install - -`apm install` reads the lock file and deploys configuration into the native formats expected by each tool — `.github/` for Copilot, `.claude/` for Claude, `.cursor/` for Cursor, `.opencode/` for OpenCode. APM generates static files and then gets out of the way. There is no runtime, no daemon, no background process. - -### Audit - -Because `apm.lock.yaml` is a committed file, standard Git tooling answers governance questions directly: - -- **What changed?** `git diff apm.lock.yaml` -- **When did it change?** `git log apm.lock.yaml` -- **What was active at a specific release?** `git show v4.2.1:apm.lock.yaml` -- **Is this environment current?** `apm audit` - -## Developer stories - -### Solo or small team (2–5 developers) - -A small team uses 5 configuration packages across 2 AI tools. - -Without APM, each developer runs 5 separate install commands, in the right order, from the right sources. When a package updates, someone notices (or doesn't), and the team re-runs the process. - -With APM, the workflow is: - -```bash -git clone the-repo -apm install -``` - -Configuration is ready. Updates are a pull request to `apm.yml`. - -### Mid-size team (10–50 developers) - -A mid-size organization maintains three layers of configuration: organization-wide security rules, team-specific coding standards, and project-level context. Different teams need different combinations. - -APM composes these layers through its dependency model. The organization publishes shared packages. Each team's `apm.yml` references the org packages it needs alongside team and project packages. `apm install` deploys them for Copilot and Claude natively; `apm compile` can merge them into instruction files for other tools. - -```yaml -packages: - # Organization layer - - name: org-security-rules - source: github:acme-corp/apm-packages - version: "^2.0" - # Team layer - - name: backend-standards - source: github:acme-corp/backend-team - version: "~1.0" - # Project layer - - name: service-context - source: ./packages/context -``` - -A new developer joining the team runs `apm install` and gets the full, correct configuration stack. There is nothing to forget. - -### Enterprise (100+ developers) - -At enterprise scale, the primary concerns shift from convenience to governance: reproducibility, audit, and policy enforcement. - -APM addresses these through mechanisms that engineering leadership and platform teams can build on: - -- **Reproducibility.** `apm.lock.yaml` guarantees that every environment — developer workstation, CI runner, staging — uses identical configuration. "Works on my machine" stops applying to agent setup. -- **Audit trail.** `git log apm.lock.yaml` provides a complete, timestamped history of every configuration change, who made it, and which pull request approved it. -- **CI enforcement.** `apm install` blocks deployment of packages containing critical hidden-character findings. `apm audit` generates SARIF reports for GitHub Code Scanning integration, providing visibility into all findings across installed packages. -- **Centralized standards.** Organization-wide packages are published once and consumed by every repository. Updates propagate through version bumps in `apm.yml`, reviewed and approved through the normal pull request process. - -## What APM adds on top of native plugin systems - -Each AI tool has its own plugin or extension system. APM does not replace these — it orchestrates across them. - -| Capability | Native plugin systems | With APM | -|---|---|---| -| Install plugins for one tool | Yes | Yes | -| Install across all tools, one command | No | Yes | -| Consumer-side version lock | No | Yes (`apm.lock.yaml`) | -| CI gate (content scanning) | No | Yes (built into `apm install`) | -| Audit trail | No | Yes (`git log apm.lock.yaml`) | -| Multi-source composition | No | Yes | - -The distinction matters: native plugin systems solve distribution for a single tool. APM solves consistency across tools, teams, and time. - -## What APM is not - -**APM is not a runtime.** It generates static configuration files in the formats each tool expects, then exits. There is no daemon, no background process, no performance overhead. - -**APM is not lock-in.** The output of `apm install` is native configuration: `.github/copilot-instructions.md`, `.claude/settings.json`, `.cursor/rules/`. If you stop using APM, the generated configuration remains and continues to work. There is nothing proprietary in the output. - -**APM is not competing with plugins.** Plugin ecosystems handle discovery and distribution for individual tools. APM handles the cross-cutting concerns — version locking, multi-tool deployment, composition, and audit — that no single plugin system addresses. - -## Getting started - -For hands-on setup and deeper topics, start here: - -- [Quick Start](../../getting-started/installation/) — install APM and configure your first project in five minutes. -- [Organization-Wide Packages](../../guides/org-packages/) — publish and maintain shared configuration packages across your organization. -- [Compilation Guide](../../guides/compilation/) — optional: generate instruction files for tools without native APM integration (Codex, Gemini). -- [Dependencies Guide](../../guides/dependencies/) — version constraints, lock file mechanics, and update workflows. diff --git a/docs/src/content/docs/guides/ci-policy-setup.md b/docs/src/content/docs/guides/ci-policy-setup.md index 0ae5ca5f9..0dc828fd3 100644 --- a/docs/src/content/docs/guides/ci-policy-setup.md +++ b/docs/src/content/docs/guides/ci-policy-setup.md @@ -239,7 +239,7 @@ Combine with `-o ` to write to a file. ## Related -- [Governance & Compliance](../../enterprise/governance/) -- conceptual overview of APM's governance model +- [Governance](../../enterprise/governance-guide/) -- conceptual overview, bypass contract, and rollout playbook - [`apm-policy.yml`](../../enterprise/apm-policy/) -- mental model and how the policy file works - [Policy Reference](../../enterprise/policy-reference/) -- full `apm-policy.yml` schema reference - [GitHub Rulesets](../../integrations/github-rulesets/) -- enforce policy as a required status check diff --git a/docs/src/content/docs/integrations/ci-cd.md b/docs/src/content/docs/integrations/ci-cd.md index a37db07ff..99c0c3934 100644 --- a/docs/src/content/docs/integrations/ci-cd.md +++ b/docs/src/content/docs/integrations/ci-cd.md @@ -103,7 +103,7 @@ apm install `apm audit --ci` verifies lockfile consistency in CI (6 baseline checks, no configuration). Add `--policy org` to enforce organizational rules (16 additional checks). For full setup including SARIF integration and GitHub Code Scanning, see the [CI Policy Enforcement guide](../../guides/ci-policy-setup/). -For content scanning and hidden Unicode detection, `apm install` automatically blocks critical findings. Run `apm audit` for on-demand reporting. See [Governance & Compliance](../../enterprise/governance/) for the full governance model. +For content scanning and hidden Unicode detection, `apm install` automatically blocks critical findings. Run `apm audit` for on-demand reporting. See [Governance](../../enterprise/governance-guide/) for the full governance model. ## Pack & Distribute diff --git a/docs/src/content/docs/integrations/github-rulesets.md b/docs/src/content/docs/integrations/github-rulesets.md index 3489ea8e1..26af8903d 100644 --- a/docs/src/content/docs/integrations/github-rulesets.md +++ b/docs/src/content/docs/integrations/github-rulesets.md @@ -160,7 +160,7 @@ The status check name must match the **job name** in your workflow file (e.g., ` ## Related - [CI Policy Enforcement](../../guides/ci-policy-setup/) -- step-by-step CI setup for policy enforcement -- [Governance & Compliance](../../enterprise/governance/) -- conceptual overview of APM's governance model +- [Governance](../../enterprise/governance-guide/) -- conceptual overview, bypass contract, and rollout playbook - [Policy Reference](../../enterprise/policy-reference/) -- full `apm-policy.yml` schema reference - [CI/CD Pipelines](../ci-cd/) -- general CI integration guide - [Manifest Schema](../../reference/manifest-schema/) -- manifest and lock file reference diff --git a/docs/src/content/docs/reference/lockfile-spec.md b/docs/src/content/docs/reference/lockfile-spec.md index 1acf583b1..72ac86353 100644 --- a/docs/src/content/docs/reference/lockfile-spec.md +++ b/docs/src/content/docs/reference/lockfile-spec.md @@ -261,6 +261,50 @@ git log -1 --format='%an <%ae> %ai' -- apm.lock.yaml In CI pipelines, `apm audit --ci` verifies lockfile consistency (exit 0 = pass, 1 = fail). Add `--policy org` for organizational policy enforcement. +### 9.1 SOC 2 evidence + +The lock file is the system of record for "what configuration was active when". +Three SOC 2-relevant questions answered directly from git: + +- **Change authorization.** Every change to `apm.lock.yaml` is reviewed in a pull + request before merge. The PR record is the change-authorization evidence. +- **Change history.** `git log apm.lock.yaml` produces a complete, signed history + of every dependency change with author, timestamp, and commit message. +- **Point-in-time state.** `git show :apm.lock.yaml` reproduces the exact + dependency set active at any tag, branch, or commit -- including past releases. + +### 9.2 Security audit / incident forensics + +When a vulnerability is disclosed in a dependency or a security incident requires +identifying which environments were exposed: + +```bash +# Was the vulnerable package ever in the lock file? +git log -p apm.lock.yaml | grep -B2 -A2 "vulnerable-package" + +# Which release included the vulnerable version? +git log --all --oneline -S 'vulnerable-package' -- apm.lock.yaml + +# What is the current state of the dependency in production? +git show production:apm.lock.yaml | grep -A5 "vulnerable-package" +``` + +### 9.3 Change management pipeline + +The lockfile-as-audit-trail model maps onto a standard 5-step change management +pipeline: + +1. **Declaration** -- developer edits `apm.yml` and opens a PR. +2. **Resolution** -- `apm install` updates `apm.lock.yaml` with pinned versions. +3. **Review** -- PR reviewers see the manifest and lockfile diff together. +4. **Verification** -- CI runs `apm audit --ci` to confirm consistency and + (optionally) policy compliance. +5. **Traceability** -- the merge commit becomes the durable record of the change, + readable by every downstream environment via `apm install` from the same ref. + +For organization-wide policy enforcement on top of this lockfile audit trail, +see [Governance](../../enterprise/governance-guide/). + ## 10. Example: Complete Lock File ```yaml From d6d2d9ddd6b0971e56eabeb55cfb33a19512b217 Mon Sep 17 00:00:00 2001 From: danielmeppiel Date: Thu, 23 Apr 2026 01:41:07 +0200 Subject: [PATCH 2/4] docs(enterprise): promote registry proxy to first-class enterprise page MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Air-gapped, Artifactory-routed deployments are an enterprise control-plane concern peer to security and governance, not a guide footnote. Previously the topic was fragmented across guides/marketplaces.md (env-var summary), governance-guide §9 (policy cache), security.md (HTTP fallback), and pack-distribute.md (offline bundles), with no single page a CISO or platform lead could read end-to-end. New page: enterprise/registry-proxy.md - Two operating modes (transparent env-var, explicit FQDN) - Bypass-prevention contract: PROXY_REGISTRY_ONLY=1 + lockfile guard, with a paste-ready trust statement for procurement - Coverage matrix (what is and is not proxy-routed: install/marketplace yes; install --mcp and ADO no; policy fetch separate) - Air-gapped CI playbook in two shapes (Shape A: CI reaches proxy; Shape B: bundle delivery) - Failure modes table grounded in the actual exception messages - Auth composition (PROXY_REGISTRY_TOKEN vs GitHub PAT) Sidebar restructure (Enterprise group): inserted Registry Proxy at order 6, between Governance and Policy Files; bumped apm-policy 6->7 and policy-reference 7->8. Cross-doc rewire: - enterprise/index.md hub: added registry-proxy to role router and section map; added platform-engineer rollout row - enterprise/security.md: 'see also' pointer from HTTP deps section - enterprise/governance-guide.md §9: distinguishing paragraph (policy- cache offline vs dep-traffic offline are different mechanisms) - guides/marketplaces.md: truncated 'Registry proxy support' section from a config snippet block to a 2-line summary + link - guides/pack-distribute.md: parenthetical positioning bundles as the offline-delivery complement to the proxy's online-routing story Build: 44 pages, all internal links valid. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- docs/astro.config.mjs | 1 + .../src/content/docs/enterprise/apm-policy.md | 2 +- .../docs/enterprise/governance-guide.md | 2 + docs/src/content/docs/enterprise/index.md | 4 +- .../docs/enterprise/policy-reference.md | 2 +- .../content/docs/enterprise/registry-proxy.md | 260 ++++++++++++++++++ docs/src/content/docs/enterprise/security.md | 2 + docs/src/content/docs/guides/marketplaces.md | 12 +- .../content/docs/guides/pack-distribute.md | 2 +- 9 files changed, 272 insertions(+), 15 deletions(-) create mode 100644 docs/src/content/docs/enterprise/registry-proxy.md diff --git a/docs/astro.config.mjs b/docs/astro.config.mjs index 895015367..f0790d964 100644 --- a/docs/astro.config.mjs +++ b/docs/astro.config.mjs @@ -87,6 +87,7 @@ export default defineConfig({ { label: 'Adoption Playbook', slug: 'enterprise/adoption-playbook' }, { label: 'Security Model', slug: 'enterprise/security' }, { label: 'Governance', slug: 'enterprise/governance-guide' }, + { label: 'Registry Proxy & Air-gapped', slug: 'enterprise/registry-proxy' }, { label: 'Policy Files', slug: 'enterprise/apm-policy' }, { label: 'Policy Reference', slug: 'enterprise/policy-reference' }, ], diff --git a/docs/src/content/docs/enterprise/apm-policy.md b/docs/src/content/docs/enterprise/apm-policy.md index 52c294c1c..a3a5bf4c0 100644 --- a/docs/src/content/docs/enterprise/apm-policy.md +++ b/docs/src/content/docs/enterprise/apm-policy.md @@ -2,7 +2,7 @@ title: "Policy Files" description: "One org-wide policy file with tighten-only inheritance for AI agent dependencies, MCP servers, and compilation targets." sidebar: - order: 6 + order: 7 --- For the full enterprise rollout playbook and bypass contract, see the [Governance Guide](../governance-guide/). diff --git a/docs/src/content/docs/enterprise/governance-guide.md b/docs/src/content/docs/enterprise/governance-guide.md index 4890af543..84636bd96 100644 --- a/docs/src/content/docs/enterprise/governance-guide.md +++ b/docs/src/content/docs/enterprise/governance-guide.md @@ -323,6 +323,8 @@ You are NOT guaranteed: ## 9. Air-gapped and offline +This section covers offline **policy** enforcement (the `apm-policy.yml` cache). For offline **dependency traffic** (routing installs through Artifactory), see [Registry Proxy & Air-gapped](../registry-proxy/). + **For air-gapped CI, run `apm audit --ci --policy ./vendored-policy.yml` as your gating check; do not rely on `apm install` enforcement.** | Network state | Install gate | Install `--mcp` | `apm audit --ci --policy ` | `apm audit --ci` (auto-discovery) | diff --git a/docs/src/content/docs/enterprise/index.md b/docs/src/content/docs/enterprise/index.md index da5094f96..eb35a2981 100644 --- a/docs/src/content/docs/enterprise/index.md +++ b/docs/src/content/docs/enterprise/index.md @@ -15,8 +15,9 @@ APM for organizations rests on three pillars: | If you are... | Start here | |---|---| -| A CISO or security reviewer | [Security Model](./security/) -> [Governance](./governance-guide/) | +| A CISO or security reviewer | [Security Model](./security/) -> [Governance](./governance-guide/) -> [Registry Proxy & Air-gapped](./registry-proxy/) | | A VP of Engineering or Tech Lead evaluating APM | [Governance](./governance-guide/) -> [Adoption Playbook](./adoption-playbook/) | +| A platform engineer rolling out APM org-wide | [Adoption Playbook](./adoption-playbook/) -> [Registry Proxy & Air-gapped](./registry-proxy/) | | A champion building an internal pitch | [Making the Case](./making-the-case/) -> [Adoption Playbook](./adoption-playbook/) | | An engineer authoring policy | [Policy Files](./apm-policy/) -> [Policy Reference](./policy-reference/) | @@ -26,5 +27,6 @@ APM for organizations rests on three pillars: - [Adoption Playbook](./adoption-playbook/) -- phased rollout from pilot team to organization-wide, with milestones, success metrics, and rollback options. - [Security Model](./security/) -- supply-chain posture: pre-deploy gate, content scanners, hidden-Unicode threat model, MCP trust boundary. Consumed verbatim by procurement and security reviewers. - [Governance](./governance-guide/) -- the flagship trust contract: bypass surfaces, install-gate guarantees, audit-log schema, rollout playbook, known gaps. Read this if you are deciding whether to make `apm audit --ci` a required check. +- [Registry Proxy & Air-gapped](./registry-proxy/) -- route dependency and marketplace traffic through Artifactory or a compatible proxy; bypass-prevention contract; air-gapped CI playbook for both online-proxy and offline-bundle shapes. - [Policy Files](./apm-policy/) -- conceptual model of `apm-policy.yml`: what it is, what it declares, how to start one. - [Policy Reference](./policy-reference/) -- complete schema for every `apm-policy.yml` field. diff --git a/docs/src/content/docs/enterprise/policy-reference.md b/docs/src/content/docs/enterprise/policy-reference.md index 9f373c044..4ff52107b 100644 --- a/docs/src/content/docs/enterprise/policy-reference.md +++ b/docs/src/content/docs/enterprise/policy-reference.md @@ -1,7 +1,7 @@ --- title: Policy Reference sidebar: - order: 7 + order: 8 --- :::caution[Experimental Feature] diff --git a/docs/src/content/docs/enterprise/registry-proxy.md b/docs/src/content/docs/enterprise/registry-proxy.md new file mode 100644 index 000000000..01fa0c6f8 --- /dev/null +++ b/docs/src/content/docs/enterprise/registry-proxy.md @@ -0,0 +1,260 @@ +--- +title: "Registry Proxy & Air-gapped" +description: "Route APM dependency and marketplace traffic through Artifactory or a compatible proxy. Two operating modes, bypass-prevention guarantees, air-gapped CI playbook." +sidebar: + order: 6 +--- + +This page documents how APM routes dependency downloads through an enterprise +registry proxy (Artifactory or compatible), the trust contract that proves +traffic cannot bypass the proxy, and the playbook for fully air-gapped CI. + +For the *policy-cache* offline story (a different mechanism), see +[Governance #9](../governance-guide/#9-air-gapped-and-offline). + +## Why this exists + +Three audiences ask the same question with different words: + +- **CISO**: "Can I prove ALL dependency traffic flows through Artifactory? + What stops a developer or a CI job from going around it?" +- **VP Engineering**: "We have standardized on Artifactory for npm and PyPI + for a decade. Does APM fit that pattern, or is it a new exception?" +- **Platform tech lead**: "How do I roll this out across N repos? What goes + in CI? What is the failure mode when the proxy is down?" + +APM answers all three with the same mechanism: a transparent proxy layer that +rewrites GitHub-based dependency downloads to fetch via Artifactory's Archive +Entry Download API, plus a lockfile-level guard that prevents bypass. + +## Operating modes + +APM supports two modes. Most teams want transparent mode; explicit FQDN mode +is for repos that must pin specific dependencies to the proxy regardless of +the developer's environment. + +### Mode 1: Transparent proxy (recommended) + +Set environment variables. APM rewrites every GitHub-hosted dependency +download (packages and `marketplace.json`) to fetch via the proxy. No changes +to `apm.yml`. + +```bash +# Required +export PROXY_REGISTRY_URL="https://art.example.com/artifactory/github" + +# Optional +export PROXY_REGISTRY_TOKEN="" # sent as Authorization: Bearer +export PROXY_REGISTRY_ONLY=1 # block all direct VCS fallback +``` + +| Variable | Purpose | +|---|---| +| `PROXY_REGISTRY_URL` | Full proxy URL including any path prefix (e.g. `/artifactory/github`). When set, all GitHub dependency archives are fetched from this base. | +| `PROXY_REGISTRY_TOKEN` | Optional bearer token sent on every proxy request. Composes with `GITHUB_APM_PAT` (see [Auth composition](#auth-composition)). | +| `PROXY_REGISTRY_ONLY` | When set to `1`, APM never falls back to direct VCS hosts. Combined with the lockfile guard below, this is the bypass-prevention contract. | + +Apply globally (shell profile, CI secrets, dev-container env) and every +`apm install` and `apm marketplace` command in the org routes through the proxy. + +:::caution +Deprecated aliases `ARTIFACTORY_BASE_URL`, `ARTIFACTORY_APM_TOKEN`, and +`ARTIFACTORY_ONLY` still work but emit a `DeprecationWarning`. Migrate to the +`PROXY_REGISTRY_*` names. +::: + +### Mode 2: Explicit FQDN in `apm.yml` + +Reference the proxy directly in the dependency string: + +```yaml +dependencies: + apm: + - art.example.com/artifactory/github/acme-corp/security-baseline#v1.4.0 +``` + +APM detects the Artifactory path and fetches via the Archive Entry Download +API for that dependency only. The rest of the manifest behaves normally. + +Use this mode when: + +- A specific dependency must always come from the proxy regardless of who + runs `apm install`. +- You are publishing a template manifest that downstream consumers should + install through your proxy without configuring environment variables. + +## Bypass-prevention contract + +This is the CISO trust statement. APM enforces "all traffic through the +proxy" with two cooperating mechanisms. + +### 1. `PROXY_REGISTRY_ONLY=1` blocks direct fetches at runtime + +When set, APM refuses to fall back to `github.com`, GitHub Enterprise Cloud, +GHES, or any other direct VCS host. If `PROXY_REGISTRY_URL` is not set or +does not match the dependency's host, the install aborts: + +``` +RuntimeError: PROXY_REGISTRY_ONLY is set but no Artifactory proxy is +configured for 'acme-corp/security-baseline'. Set PROXY_REGISTRY_URL or +use explicit Artifactory FQDN syntax. +``` + +### 2. Lockfile validation guard prevents replay-from-bypass + +When a download routes through the proxy, the resulting `apm.lock.yaml` +entry pins the proxy as the source of truth: + +```yaml +dependencies: + - repo_url: acme-corp/security-baseline + host: art.example.com + registry_prefix: artifactory/github + resolved_commit: a1b2c3d4... + content_hash: "sha256:9f86d081..." +``` + +On every subsequent `apm install` with `PROXY_REGISTRY_ONLY=1`, APM scans +the lockfile. If any entry is locked to a direct VCS host (github.com, GHE +Cloud, GHES) instead of the proxy, the install aborts and lists the +conflicting dependencies: + +``` +ERROR: PROXY_REGISTRY_ONLY=1 but the following lockfile entries are +locked to direct VCS hosts and would bypass the proxy: + - acme-corp/security-baseline (host: github.com) + - other-org/skill-pack (host: ghes.corp.example.com) +Run 'apm install --update' to re-resolve through the proxy. +``` + +`apm install --update` re-resolves dependencies through the active proxy +and rewrites the lockfile. + +### Trust statement (paste into procurement responses) + +> When `PROXY_REGISTRY_ONLY=1` is set in CI, APM cannot install a +> dependency that did not flow through the configured proxy. Any attempt to +> install a lockfile entry pinned to a direct VCS host aborts with a +> non-zero exit code before any download occurs. + +## Coverage matrix + +What is and is not routed through the proxy: + +| Surface | Routed via proxy | Notes | +|---|---|---| +| `apm install` (GitHub-hosted deps) | Yes | Packages from github.com, GHE Cloud, GHES | +| `apm install` (Azure DevOps deps) | **No** | ADO uses a different download path; Artifactory backends recognize GitHub/GitLab archive prefixes only | +| `apm install --mcp` | **No** | MCP servers come from a separate registry, not GitHub archives | +| `apm marketplace add` / `browse` / `search` / `update` | Yes | `marketplace.json` fetched via Archive Entry Download; falls back to GitHub Contents API unless `PROXY_REGISTRY_ONLY=1` | +| `apm pack` / `apm unpack` | N/A | Operate offline once dependencies are local; see [Air-gapped CI playbook](#air-gapped-ci-playbook) | +| Policy file fetch (`apm-policy.yml`) | **No** | Policy discovery uses the GitHub API directly. See [Governance #9](../governance-guide/#9-air-gapped-and-offline) for the policy-cache offline story. | + +When `PROXY_REGISTRY_ONLY=1` is set and a surface is not proxy-routed (ADO, +MCP), APM aborts rather than silently fetching direct. + +## Air-gapped CI playbook + +The "fully air-gapped" story has two valid shapes. Pick based on whether CI +has network reach to the proxy. + +### Shape A: CI can reach the proxy + +CI is on the corp network with Artifactory access; only the public internet +is blocked. + +```yaml +# .github/workflows/ci.yml +env: + PROXY_REGISTRY_URL: https://art.corp.example.com/artifactory/github + PROXY_REGISTRY_TOKEN: ${{ secrets.ARTIFACTORY_TOKEN }} + PROXY_REGISTRY_ONLY: "1" + +jobs: + install: + runs-on: self-hosted + steps: + - uses: actions/checkout@v4 + - uses: microsoft/apm-action@v1 + - run: apm install + - run: apm audit --ci --policy ./vendored-policy.yml +``` + +`apm install` routes every dependency and `marketplace.json` fetch through +Artifactory. `apm audit --ci --policy` enforces governance from a vendored +policy file with no network calls (see [Governance #9](../governance-guide/#9-air-gapped-and-offline)). +The lockfile guard catches any entry that would bypass the proxy on +re-install. + +### Shape B: CI has no network at all (bundle delivery) + +CI cannot reach the proxy or the public internet. Build a bundle on a +connected host, transport it, restore it offline. + +```bash +# On a connected build host (with proxy configured) +export PROXY_REGISTRY_URL=https://art.corp.example.com/artifactory/github +export PROXY_REGISTRY_ONLY=1 +apm install +apm pack --archive -o ./artifacts/ + +# Transport ./artifacts/*.tar.gz to the air-gapped network + +# In air-gapped CI (no APM, no Python, no network) +tar xzf bundle.tar.gz -C . +# Files are deployed; agents can read them immediately +``` + +See [Pack & Distribute](../../guides/pack-distribute/) for bundle structure +and the `apm-action` restore mode. + +### Prewarming the policy cache + +Independent of dependency traffic, the *policy* fetch goes direct to +GitHub. For air-gapped runs that need policy enforcement on `apm install`, +prewarm `/apm_modules/.policy-cache/` or use +`apm audit --ci --policy ` as the gating check. Details in +[Governance #9](../governance-guide/#9-air-gapped-and-offline). + +## Failure modes + +| Symptom | Cause | Resolution | +|---|---|---| +| `RuntimeError: PROXY_REGISTRY_ONLY is set but no Artifactory proxy is configured for ''` | `PROXY_REGISTRY_ONLY=1` set but `PROXY_REGISTRY_URL` is empty, or the dep is on an unproxied host (ADO) | Set `PROXY_REGISTRY_URL`, or use explicit FQDN syntax in `apm.yml`, or unset `PROXY_REGISTRY_ONLY` for that dep type | +| `ERROR: PROXY_REGISTRY_ONLY=1 but the following lockfile entries are locked to direct VCS hosts` | Lockfile was generated before the proxy was configured | Run `apm install --update` to re-resolve through the proxy | +| HTTP 401/403 from the proxy | Missing or invalid `PROXY_REGISTRY_TOKEN`, or token lacks read on the upstream repo | Verify the token has Artifactory read on the repository being fetched | +| Proxy unreachable (timeout, DNS) with `PROXY_REGISTRY_ONLY=1` | Proxy down, network partition | Install fails closed. Restore proxy connectivity or fall back to a pre-built [bundle](../../guides/pack-distribute/) | +| `DeprecationWarning: ARTIFACTORY_BASE_URL is deprecated` | Using legacy env-var names | Rename to `PROXY_REGISTRY_*`. Old names continue to work but will be removed in a future major release | +| Warning: lockfile entry locked to proxy is missing `content_hash` | Older proxy-routed entry without integrity hash | Run `apm install --update` to populate. Without `content_hash`, a tampered proxy could redirect downloads without detection | + +## Auth composition + +`PROXY_REGISTRY_TOKEN` and the GitHub PAT (`GITHUB_APM_PAT`, `GITHUB_TOKEN`, +`GH_TOKEN`) are independent and used for different request paths: + +- Requests to `PROXY_REGISTRY_URL` send `Authorization: Bearer + `. +- Requests to `github.com` / GHE / GHES (only possible when + `PROXY_REGISTRY_ONLY` is unset) use the GitHub PAT. + +In a hybrid setup where `PROXY_REGISTRY_ONLY` is unset and some dependencies +fall back to direct GitHub (because they are not mirrored), both tokens are +used: proxy traffic auths with the bearer, direct traffic auths with the +PAT. Set both in CI secrets if you support hybrid. + +For strict environments, set `PROXY_REGISTRY_ONLY=1` and only configure +`PROXY_REGISTRY_TOKEN`. The GitHub PAT is then unused at install time. + +## HTTP proxies + +The proxy can be served over HTTP, but APM treats this as an insecure +dependency channel. The same approval surface applies as for any HTTP +dependency: see [HTTP (insecure) dependencies](../security/#http-insecure-dependencies). +Production deployments should always use HTTPS. + +## See also + +- [Governance #9](../governance-guide/#9-air-gapped-and-offline) -- offline policy enforcement (different mechanism) +- [Security Model](../security/) -- attack surface, content scanning, HTTP dep handling +- [Pack & Distribute](../../guides/pack-distribute/) -- bundle delivery for fully disconnected CI +- [Marketplaces](../../guides/marketplaces/) -- marketplace command surface diff --git a/docs/src/content/docs/enterprise/security.md b/docs/src/content/docs/enterprise/security.md index 719deeecc..ee2b059e3 100644 --- a/docs/src/content/docs/enterprise/security.md +++ b/docs/src/content/docs/enterprise/security.md @@ -81,6 +81,8 @@ These controls make the decision visible, but they do **not** make HTTP safe: - On the first HTTP fetch (or any update fetched over HTTP), the lockfile's `resolved_commit` and `content_hash` come from that same untrusted channel. They improve replay detection later, but they do not establish trustworthy provenance for the initial fetch. - APM explicitly suppresses git credential helpers for HTTP clone and `ls-remote` operations so stored tokens from Keychain, Credential Manager, `gh auth`, or other helpers are not sent over plaintext HTTP. +For routing all dependency traffic through an enterprise proxy (Artifactory or compatible), see [Registry Proxy & Air-gapped](../registry-proxy/). + ## Content scanning ### The threat diff --git a/docs/src/content/docs/guides/marketplaces.md b/docs/src/content/docs/guides/marketplaces.md index 1f985feb5..0d160f3e3 100644 --- a/docs/src/content/docs/guides/marketplaces.md +++ b/docs/src/content/docs/guides/marketplaces.md @@ -197,17 +197,7 @@ apm marketplace update ## Registry proxy support -When `PROXY_REGISTRY_URL` is set, marketplace commands (`add`, `browse`, `search`, `update`) fetch `marketplace.json` through the registry proxy (Artifactory Archive Entry Download) before falling back to the GitHub Contents API. When `PROXY_REGISTRY_ONLY=1` is also set, the GitHub API fallback is blocked entirely, enabling fully air-gapped marketplace discovery. - -```bash -export PROXY_REGISTRY_URL="https://art.corp.example.com/artifactory/github" -export PROXY_REGISTRY_ONLY=1 # optional: block direct GitHub access - -apm marketplace add anthropics/skills # fetches via Artifactory -apm marketplace browse skills # fetches via Artifactory -``` - -This builds on the same proxy infrastructure used by `apm install`. See the [Registry Proxy guide](../registry-proxy/) for full configuration details. +Marketplace commands (`add`, `browse`, `search`, `update`) honor the `PROXY_REGISTRY_URL` and `PROXY_REGISTRY_ONLY` environment variables, fetching `marketplace.json` through the configured proxy with optional GitHub Contents API fallback. See [Registry Proxy & Air-gapped](../../enterprise/registry-proxy/) for full configuration, the bypass-prevention contract, and the air-gapped CI playbook. ## Manage marketplaces diff --git a/docs/src/content/docs/guides/pack-distribute.md b/docs/src/content/docs/guides/pack-distribute.md index 600582ff2..900c03bab 100644 --- a/docs/src/content/docs/guides/pack-distribute.md +++ b/docs/src/content/docs/guides/pack-distribute.md @@ -16,7 +16,7 @@ A bundle removes all of that. You resolve once, pack the output, and distribute Common motivations: - **CI cost reduction** — resolve once, fan out to many jobs -- **Air-gapped environments** — no network access at deploy time +- **Air-gapped environments** — no network access at deploy time (for environments where CI *can* reach an internal proxy, see [Registry Proxy & Air-gapped](../../enterprise/registry-proxy/) -- bundles are the offline-delivery story; the proxy is the online-routing story) - **Reproducibility** — the bundle is a snapshot of exactly what was resolved - **Faster onboarding** — new contributors get pre-built context without running install - **Audit trail** — attach the bundle to a release for traceability From 51cea07e2a878b926c510470c89bacf9f4ae64ff Mon Sep 17 00:00:00 2001 From: Daniel Meppiel <51440732+danielmeppiel@users.noreply.github.com> Date: Thu, 23 Apr 2026 01:45:57 +0200 Subject: [PATCH 3/4] Update docs/src/content/docs/enterprise/making-the-case.md Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- docs/src/content/docs/enterprise/making-the-case.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/docs/src/content/docs/enterprise/making-the-case.md b/docs/src/content/docs/enterprise/making-the-case.md index ae349c5d1..815420e24 100644 --- a/docs/src/content/docs/enterprise/making-the-case.md +++ b/docs/src/content/docs/enterprise/making-the-case.md @@ -38,8 +38,7 @@ dependencies: - microsoft/apm-sample-package#v1.0.0 - github/awesome-copilot/plugins/context-engineering mcp: - - name: io.github.github/github-mcp-server - transport: http + - io.github.github/github-mcp-server ``` This file is version-controlled, reviewed in pull requests, and readable by anyone on the team. From e1ae03fd4c05425e13a54e08e13fd37ec82c2b3f Mon Sep 17 00:00:00 2001 From: Daniel Meppiel <51440732+danielmeppiel@users.noreply.github.com> Date: Thu, 23 Apr 2026 01:46:25 +0200 Subject: [PATCH 4/4] Update docs/src/content/docs/reference/lockfile-spec.md Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- docs/src/content/docs/reference/lockfile-spec.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/src/content/docs/reference/lockfile-spec.md b/docs/src/content/docs/reference/lockfile-spec.md index 72ac86353..1c42bc202 100644 --- a/docs/src/content/docs/reference/lockfile-spec.md +++ b/docs/src/content/docs/reference/lockfile-spec.md @@ -268,8 +268,8 @@ Three SOC 2-relevant questions answered directly from git: - **Change authorization.** Every change to `apm.lock.yaml` is reviewed in a pull request before merge. The PR record is the change-authorization evidence. -- **Change history.** `git log apm.lock.yaml` produces a complete, signed history - of every dependency change with author, timestamp, and commit message. +- **Change history.** `git log apm.lock.yaml` produces a complete, tamper-evident + history in git of every dependency change with author, timestamp, and commit message. - **Point-in-time state.** `git show :apm.lock.yaml` reproduces the exact dependency set active at any tag, branch, or commit -- including past releases.