Macro Security And Trust Model
ProtoML macros are still the highest-trust extension surface in the system, but the trust workflow is now formalized so teams can inspect, sign, and classify them without building a heavy PKI layer into every document.
Three separate concepts
- Risk flags: what the macro actually does, such as JavaScript or external URLs
- Signature status: whether the file matches a detached signature sidecar
- Author trust: whether the signing author is marked trusted or untrusted in a registry
ProtoML combines these into one effective trust value instead of mixing the concepts together.
Effective trust levels
trusted: valid signature by a trusted author, or a bundled built-in macro that matches the shipped hash manifest, and no hard risk violationsunknown: no signature or no trusted registry author match, but also no hard risk violationuntrusted: invalid signature, untrusted author, JavaScript, external URLs, or imported untrusted content
Important simplification
Plain HTML by itself is not treated as an automatic trust failure anymore. Macros are HTML-oriented by design, so HTML is only tracked as a capability flag. The hard downgrade conditions are JavaScript and external URLs.
Bundled built-in macros are identified by their real file location and a shipped hash manifest, not just by writing {{macro_dir}} in the document. That prevents newly dropped files in the built-in directory from becoming trusted automatically.
How to read common trust outcomes
- Bundled built-in macro plus matching shipped hash and no hard risk flag: usually
trusted - Bundled built-in macro with JavaScript or external URLs: still
untrusted - Normal local custom macro without signatures: usually
unknown - Signed custom macro with trusted registry author and no hard risk flag:
trusted - Imported
.pmlfile without trust information: usuallyunknown
Detached signatures instead of inline syntax
Macros and .pml files are signed via detached sidecars such as warning.pml.sig.json. This keeps ProtoML syntax clean and lets the same signing flow work for macros and full documents.
protoparser sign macro "./macros/warn_box.pml" "./keys/alice-private.pem" "Alice" alice-main
protoparser verify macro "./macros/warn_box.pml" -trustRegistry="./my-registry"
Detached sidecars outside a registry
The detached *.sig.json format also works without any registry at all.
Author side:
- sign the macro or document
- distribute the original file and the generated
*.sig.jsontogether - share the public key through a documented channel
User side:
- keep the file and sidecar together
- run
protoparser verify ...to verify integrity and authorship cryptographically - use a trust registry only if the author should also resolve to
trustedoruntrusted
Without a registry, signed content can still be verified, but it typically remains unknown rather than trusted.
Registry author model
The registry is used as an author trust directory, not as a sandbox. It can declare authors and their public keys, plus package metadata for discovery.
{
"version": 1,
"authors": [
{
"name": "Alice",
"trust": "trusted",
"keys": [
{
"id": "alice-main",
"public_key": "-----BEGIN PUBLIC KEY----- ..."
}
]
}
]
}
What validation enforces
validatereports untrusted macros and imported.pmlfiles-trust=warnwarns but allows rendering-trust=strictblocks rendering on untrusted macro or imported document trust failuresunknowncontent is visible in trust reports, but does not fail by default
What was intentionally left out
- No popularity or download-count trust scoring
- No mandatory online lookup for normal local rendering
- No separate signature syntax inside ProtoML blocks
Those ideas create substantial overhead and unclear semantics. Detached signatures plus author registries give most of the practical value with much less maintenance cost.
Recommended team policy
- Keep signed production macros in version-controlled repositories
- Publish trusted authors in one internal registry
- Run
protoparser trustandvalidate -trust=strictin CI for sensitive documents - Review any macro that contains JavaScript or external URLs manually
- Prefer bundled built-in macros for common safe defaults before introducing new custom packs