Why does EK9 require capability declarations for publishable packages?
← Package Capability Security · Ref: Q1272
Every major software supply chain attack of the last decade shares the same kill chain: a compromised dependency quietly accesses system resources — reading environment variables, opening network connections, writing files — that its stated purpose does not require, and exfiltrates data. A JSON parser and a credential-stealing trojan look identical in their published metadata on npm, PyPI, Maven Central, or crates.io. Nothing in those ecosystems tells a consumer what a dependency will do at the system level.
EK9 closes the gap structurally at the compiler. Every publishable package must declare the gated system types it uses in a 'capabilities' list. The compiler verifies the declarations match the actual code: you cannot use 'Stdout', 'TCP', 'File', or 'EnvVars' in a publishable module without declaring the matching capability. When a previously-pure package suddenly adds 'org.ek9.lang::TCP' to its capabilities list, that change is visible to every consumer the moment they fetch the new version from the repository — before a single line of it executes.
THE TWO CAPABILITIES EVERY ATTACK NEEDS
1. Reading secrets — EnvVars for API keys, File for credential files, Stdin for pipes 2. Exfiltration — TCP for network sockets, HTTPRequest for REST calls, File for disk
EK9 gates both. A package that declares 'capabilities <- ["org.ek9.lang::TCP"]' has explicitly said 'I need network access' — a claim that consumers can evaluate against the package's advertised purpose. A package that declares no network capability literally cannot open a socket in its non-dev code; the compiler refuses to emit the bytecode.
MOST PACKAGES NEED ZERO CAPABILITIES
A JSON parser. A collection library. A string-manipulation utility. A mathematical package. None of them touch system resources — they should declare no capabilities, and the compiler enforces that pure-computation shape. When a legitimate library author updates their package they can be confident no accidental capability has crept in; when an attacker tries to insert one, the change is unmissable.
THE COST
A few extra lines in your 'defines package' block when you write a publishable library. The occasional compile error when you start using a new gated type and forget to declare it. That's the entire developer tax.
THE BENEFIT
Structural supply chain defence. No silent access escalation. No JSON parser that quietly reads your AWS credentials. No 'helper utility' that opens a reverse shell. The capability change is a compile error before it's a compromise.
See Q1270 for what makes a package publishable. See Q1271 for the capability declaration syntax. See Q1273 for the full gated types list. See Q1277 for error E12010.
Example
defines module qa.packagecapabilities.whyrationale defines package version <- 1.0.0-0 description <- "Shows a pure computation library that needs no capabilities" license <- "MIT" publicAccess <- true capabilities <- ["org.ek9.lang::Stdout"] defines function explainWhy() stdout <- Stdout() stdout.println("Capability declarations make supply chain attacks structurally visible.") stdout.println("When a new version declares org.ek9.lang::TCP, every consumer sees it before it runs.")
Other ways to ask this
- What problem does EK9 capability security solve?
- Why can't I just use any type in a published EK9 package?
- What supply chain attack does EK9 capability enforcement prevent?
- Explain the rationale for gated types in EK9.
Coming from another language?
npm (2015-2025): dozens of typosquatted and maintainer-hijack attacks; no capability model. PyPI (2022-2025): credential-stealing packages active for days before detection; no compile-time defence. Maven Central: no runtime permission enforcement beyond Java SecurityManager (deprecated). crates.io: safe Rust but no capability metadata. Go modules: no capability concept. EK9: compile-time capability enforcement at the module boundary — the compiler refuses to emit bytecode for undeclared gated type usage.
Keywords: rationale, gated type, defence, supply chain, security, why, attack, capability