Distribution Artifact Leakage
Use this reference when a package, image, release archive, browser bundle, workflow artifact, model bundle, prompt package, git history, or exported support bundle may expose material that should remain server-side or confidential.
Publish Boundary
Treat distributed artifacts as public unless the organization has a stronger approved control around access, retention, and revocation.
Common public or semi-public distribution surfaces:
- npm, NuGet, PyPI, Maven, RubyGems, Go modules, and similar packages
- Docker and OCI images
- Helm charts and deployment bundles
- browser, mobile, desktop, and Electron bundles
- CI/CD artifacts, release archives, test reports, screenshots, and support bundles
- SBOMs, provenance files, vulnerability reports, and debug bundles
- model, agent, prompt, workflow, or MCP/server tool packages
- git history available to repository readers, forks, mirrors, or vendors
Obfuscation and minification do not protect secrets, prompts, source code, security policy, routing logic, business logic, or proprietary model/agent configuration.
Universal Block List
Block these from distributed artifacts unless explicitly approved as public:
.env*, credentials, keys, certificates, connection strings, tokens, cookies, and local secrets.git, git remotes, reflogs, patch files, and local branch metadataprompts/, internal agent instructions,SKILL.md,.agent.md, tool schemas, routing logic, and orchestration policy- source maps, PDBs, debug symbols, traces, heap dumps, and verbose logs
- tests, fixtures with real data, screenshots, recordings, and support bundles
- server-only modules inside client packages
- Terraform plans, generated configuration with secrets, and deployment output containing identifiers or keys
- package-manager caches that contain private feed URLs, tokens, or credentials
- AI model weights, embeddings, indexes, or evaluation datasets not approved for release
Package Publish Checks
Before publish:
- Prefer an allowlist where the ecosystem supports it.
- Run the ecosystem pack or dry-run command.
- Inspect the produced file list and, where practical, the archive contents.
- Fail publish if confidential, server-side, or unrelated material appears.
- Save the inspected file list as PR or release evidence.
Ecosystem notes:
- npm: prefer the
filesallowlist inpackage.json; do not rely on.npmignorealone. - .NET/NuGet: set prompts, appsettings, debug symbols, internal content, and test assets to
Pack="false"unless intentionally public. - Python: use explicit package discovery includes; exclude tests, prompts, scripts, local config, and notebooks with outputs unless intentionally distributed.
- Java/Maven/Gradle: inspect generated jars/wars and source jars; keep local config and test fixtures out of published artifacts.
- Go: check module contents and avoid committing generated files that embed local paths or secrets.
Docker and OCI Image Checks
Before push:
- Confirm the Dockerfile uses a minimal runtime-only final stage.
- Confirm
.dockerignorekeeps sensitive files out of the build context. - Use BuildKit secrets or the platform equivalent for private feeds and build-time credentials.
- Do not pass secrets through Docker build args, especially when provenance is enabled.
- Inspect image history and exported filesystem when leakage risk is high.
- Confirm the runtime image does not include package-manager caches, source code, tests, or build tooling unless required.
Build context hygiene, .dockerignore placement and depth traps
A build context is a leakage surface and a size surface: .venv/ (with tokens and private feed URLs), .git/, and tool caches ride into the context when ignored incompletely. Two traps are production-verified:
- Place
.dockerignoreat the build context root, not the service subdirectory. When the build context points above the service directory (e.g.context: ../..in a monorepo so a sharedsrc/,pyproject.toml, and lockfile are reachable), the remote build tars up everything under that root, with no root.dockerignore, that includes.venv/(196 MB+ once real dependencies land),.git/, and cache directories. This silently "works" while the context is small, then fails outright withremote build failed: archive/tar: write too long, a confusing error naming no offending file. Confirm exactly what the Dockerfile'sCOPYinstructions reference before excluding a directory, so nothing needed is silently dropped. - Use
**/target, nottarget, to exclude nested build-artifact directories. A baretargetentry only excludes atarget/directory at the exact root of the build context; nested directories (e.g.src-tauri/target/in a workspace) are not matched and are still sent to the remote build. A single Rust releasetarget/can contain.libfiles over 800 MB, trippingarchive/tar: write too longon ACR remote builds. The same glob rule applies tonode_modules,dist,.next, and similar artifacts, use**/<dirname>for anything that can appear at depth.
Useful checks:
# Check layers and command history for obvious leaks.
docker history --no-trunc myimage:local
# Export filesystem for review in high-risk releases.
container_id=$(docker create myimage:local)
docker export "$container_id" -o image-rootfs.tar
docker rm "$container_id"
tar -tf image-rootfs.tar | sort > image-rootfs-files.txt
# Look for common sensitive paths.
grep -Ei '(^|/)(\.git|\.env|id_rsa|id_ed25519|appsettings\..*\.json|.*\.pdb|.*\.map|SKILL\.md|\.agent\.md)$' image-rootfs-files.txtBlock images that include:
.git,.env*, private keys, certificates, local app settings, or user profile directories- prompt files,
SKILL.md,.agent.md, and internal orchestration instructions - source maps, PDBs, tests, or source code not required at runtime
- package-manager caches with credentials or private feed metadata
- build tools, compilers, SDKs, and scanners in runtime images unless required by the workload
CI/CD Artifact and Log Checks
- Validate artifact directories before upload.
- Keep retention short and justified unless audit policy requires longer retention.
- Never echo secrets or derived secrets.
- Mask derived secret values before any command can print them.
- Treat Terraform plans, deployment output, screenshots, traces, and support bundles as sensitive by default.
- Run full-repository secret scans before release branches or tags when history exposure matters.
- Keep vulnerability reports and SBOMs accessible only to intended consumers if they reveal exploitable inventory.
Git History Remediation
If a secret entered git history:
- Rotate the credential immediately.
- Identify every branch, tag, fork, mirror, artifact, and log that may contain it.
- Clean history with an approved tool such as
git filter-repoor BFG. - Force-push only after coordination and approval.
- Verify with a fresh clone and full-history secret scan.
- Record the incident, affected secret, rotation evidence, cleanup command, and verification result.
Do not treat deleting the file from the current tree as remediation.
Prompt and Tool-Definition Protection
Classify prompts and tool definitions before packaging:
- Public: user-facing text or examples that provide no sensitive operational advantage.
- Internal: implementation guidance that can be shared with repository contributors but not customers or public packages.
- Confidential: system prompts, orchestration policy, tool catalogs, routing logic, security posture, business logic, model configuration, and agent runtime configuration.
Confidential prompts and tool definitions must stay server-side. Load them from controlled configuration, Key Vault, App Configuration, Foundry storage, mounted secrets, or an equivalent runtime store.
Do not embed confidential prompts in compiled strings, browser bundles, Docker layers, NuGet resources, npm packages, mobile/desktop bundles, model packages, or workflow artifacts.
Review Evidence
For a publish or release PR, attach or summarize:
- pack or dry-run file list
- image history and filesystem inspection result, if an image is published
- artifact validation result
- secret scan scope and result
- SBOM and provenance handling decision
- explicit prompt/tool classification result when AI components are packaged
- waiver or exception approvals with owner and expiry