PATTERN Cited by 1 source
Package Rule auto-generation
When a security tool's allowlist depends on content hashes (SHA-256 of a binary, of a package artifact, of a container layer), every upstream upgrade invalidates the rule. Manual rotation is a tax that scales with both package count and release cadence; on any serious fleet it becomes the top source of false-positive blocks.
Package Rule auto-generation handles this by letting operators author allowlist entries at a high-level package abstraction (name + source) and running a scheduled workflow that resolves each to the current concrete hash and emits low-level Binary rules to the enforcer.
Shape¶
# Author this:
- package_type: homebrew
package: vim
- package_type: github
package: rust-lang/rust-analyzer
[ruleset repo: Package rules as config-as-code]
│ (cron / webhook trigger)
↓
[workflow runner]
│
│ for each Package rule:
│ fetch current SHA-256 from official source
│ (Homebrew bottle API / GitHub release asset)
│
↓
[emit fresh Binary rules]
│
↓
[sync server → fleet]
- Config-as-code in same repo as other rules. PRs are the change surface — review, audit log, rollback all inherited from Git.
- Scheduled refresh — cron or webhook on the upstream source. Cadence needs to be faster than the upstream package's typical release interval so newly-upgraded local installs find a matching Binary rule on their first block.
- Workflow runs on fleet-matching architecture. Hashes differ per architecture — ARM vs x86 — so the workflow must run on the same architecture set the fleet uses or produce hashes the fleet won't match.
- Official-source fetch only. The whole point is to follow the authoritative release; if the workflow pulls from a cache or a mirror you've broadened the trust boundary.
- Additive rule emission. Old Binary rules aren't immediately deleted when a new version lands — users on the previous version still need them. Expiry is a separate slower sweep.
- Monitor for failure. A hung workflow silently stops updating
rules → the first user to
brew upgradegets blocked. Alerts on "time since last successful package-rule regeneration" catch this.
Extensibility¶
The package_type field is the extension point: new source systems
(npm, pip, Terraform providers, Cargo crates, Docker images) each
get their own resolver. The rule authors' mental model stays
"name + source"; operators add resolvers as new package managers
become part of the fleet's tool surface.
When to use¶
- Allowlist / blocklist entries that depend on content hash (binary authz, SRI for scripts, container image digests).
- Entries source-controlled from package managers with official indexes (Homebrew, GitHub releases, npm, PyPI, crates.io).
- Refresh cadence faster than the team's manual review cadence.
- Hash-rotation-on-upgrade would otherwise produce a steady stream of spurious enforcement failures.
When not to use¶
- Entries that don't need to follow upstream (pinned versions for compliance / reproducibility reasons).
- Tools whose upstream doesn't publish signed or verifiable artifacts (you'd be automating trust of tampering).
- When the workflow can't run on fleet-matching architecture.
Scale signal from the canonical instance¶
At Figma, ~200 Package rules expand to ~80,000 Binary rules. That ratio — two orders of magnitude — is the upper-bound evidence that hand-rotation wouldn't have scaled: the operator surface stays human-manageable while the enforcer surface covers every version in the fleet's recent release window.
A downside surfaced at that scale: large rule sets stress the initial-sync on a new device. 80K rule sync occasionally timed out mid-delivery → incomplete rule set → critical-app block on a brand-new laptop. Mitigated by pinning MDM / Chrome / Slack / Zoom in Santa's static config as patterns/static-allowlist-for-critical-rules.
Seen in¶
- sources/2026-04-21-figma-rolling-out-santa-without-freezing-productivity — Figma authored Package rules as config-as-code alongside the rest of Santa config in a GitHub repo. A workflow on macOS runners (to match fleet architecture) fetches current SHA-256 from each official source every 30 minutes and emits fresh Binary rules to Rudolph. Canonical wiki instance. 200 → 80,000 rule amplification. Identified the initial-sync failure mode at 80K rules and hedged it with static allowlist entries.
Related¶
- concepts/binary-authorization — the canonical enforcement context.
- systems/santa / systems/rudolph — the reference tools.
- patterns/static-allowlist-for-critical-rules — the complementary pattern for critical rules that must survive sync failure.
- patterns/data-driven-allowlist-monitoring-mode — the allowlist-origin pattern; Package rules cover one of the three residual-category mitigations (unsigned from package managers).
- concepts/content-addressed-caching — the cousin concept in build systems; same underlying idea (hash = version identity) applied to a different problem.