8. Security considerations
- Visibility is a producer claim, not authentication.
identity.visibility: publicasserts an intent to distribute, not a proven fact about any remote state; a consumer MUST NOT treat it as evidence that a repository, package, or endpoint is reachable without a token.privateis the assertion a consumer may act on by declining to disclose. Likeidentity.namespace, the value carries no authority of its own, and the default it resolves to (Section 4.3) governs local derivation only — never a change to remote state. - Namespace claims are unverified. A producer writing
identity.namespace: org.exampleasserts a relationship toexample.orgbut offers no proof. Consumers MUST treat namespaces as identifiers, not as authentication, and MUST NOT confer trust on the basis of namespace value alone. The same applies to extension namespaces (Section 6). - No auto-fetch of URLs. Consumers MUST NOT follow any
links[].url,repositories[].url, extension-defined URL, or any other URL field automatically. Fetching is a dedicated action a consumer MAY take only with clear user consent. The one exception isincludes(§4.9): listing a URL there is the author’s consent to fetch it, and a consumer SHOULD offer an offline mode that does not. - Remote includes are build inputs. A remote include changes what every including document means, at the moment its server changes. Producers SHOULD pin a remote include by digest, or name a URL that does not move (a tag or a commit, not a branch), wherever a silent change would matter.
- Extension trust domain. Extension namespaces are arbitrary data. A consumer that interprets an extension namespace does so under its own authority; the specification makes no claim about the trustworthiness of extension content. Consumers SHOULD validate extension contents against the extension’s own schema before acting on them.
- No secrets. Documents MUST NOT contain secrets (API keys, passwords, private keys). Secrets belong in out-of-band mechanisms (environment variables, secret stores, encrypted
.envfiles). Producers SHOULD reject documents that include values matching common secret patterns; detection is best-effort. - Secret provisioning subtrees are NOT exceptions — they never carry real secrets. A consumer MAY define a dev/CI secret-provisioning manifest (e.g.
org.projectfile.ci.secrets) whosevalue:entries are dev defaults (mariadb) or explicit placeholders (CHANGEME) and whosedocker:entries name a generator run at provisioning time (so no value is committed at all). Such a subtree is a recipe for materializing a.secrets/tree on a dev host or CI runner — it is NOT a store of production secret values. A real production secret is overlaid at runtime via the consumer’s deployment binding (e.g.org.projectfile.ci’s per-target<target>.credentialsmap, §6 extension schema), never committed in the document. A provisioning subtree carrying anything that looks like a real secret value SHOULD be rejected by producers as a likely §8 violation. - Interpolation reads, never executes. A
${…}reference (§3.8) resolves to a value already present in the merged document; it never names a file, a command, or a network location. A consumer MUST NOT extend the address grammar with anything that reads outside the document. Note that a remote include can plant a reference that resolves against the including document’s fields — that is the mechanism working as designed, and it is why §8’s no-secrets rule matters: a document that carries no secrets has none to leak into a fragment’s output. - Path traversal. Path-valued fields (
license.file) MUST resolve to a location inside the project directory after normalization. Consumers MUST reject paths that, after normalization, contain..segments crossing the project root, that are absolute, or that include a Windows drive letter (C:\,\\?\, etc.). Symlink behavior is consumer-defined: consumers operating in adversarial contexts SHOULD refuse paths whose resolution escapes the project directory; consumers operating on trusted local trees MAY follow symlinks. - Parser safety. Each accepted encoding has its own parser hazards. YAML consumers MUST use a YAML 1.2 safe loader; custom tag handling (e.g.,
!!python/object, language-specific object construction tags) MUST be disabled. TOML consumers SHOULD reject documents with duplicate keys (the TOML 1.0 spec already requires this; some tolerant parsers do not). JSON consumers SHOULD use a parser that rejects duplicate object keys or warns about them. - Multi-file ambiguity. Multiple
projectfile.*files in one project root fail validation by default (§3.5). Because no file is selected by a side-channel signal such as modification time, there is no mtime-manipulation hazard for an attacker to exploit by swapping in a malicious sibling.