Skip to content

Commit dd2a5e0

Browse files
committed
docs: substantive CRG C annotation (EXPLAINME.adoc)
1 parent 0b6bb17 commit dd2a5e0

1 file changed

Lines changed: 179 additions & 8 deletions

File tree

EXPLAINME.adoc

Lines changed: 179 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,196 @@
11
// SPDX-License-Identifier: PMPL-1.0-or-later
2-
= php-aegis — Show Me The Receipts
2+
// SPDX-FileCopyrightText: 2026 Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk>
3+
= php-aegis — PHP Security Toolkit — Show Me The Receipts
34
:toc:
45
:icons: font
56

6-
The README makes claims. This file backs them up.
7+
The README makes claims. This file backs them up. php-aegis is a PHP 8.1+
8+
security toolkit: input validation, context-aware sanitization, security headers,
9+
and (uniquely) W3C-compliant RDF/Turtle escaping. Named after the mythological
10+
shield of Zeus.
11+
12+
== Claim: Zero-dependency, type-safe, context-aware output escaping
713

814
[quote, README]
915
____
10-
See link:POSITIONING.md[POSITIONING.md] for detailed guidance.
16+
A PHP security and hardening toolkit providing input validation, sanitization,
17+
and security utilities. Zero Dependencies — core library has no external
18+
dependencies. Type Safety — full strict_types enforcement throughout.
19+
Context-Aware Sanitization — HTML, JS, CSS, URL, and JSON output escaping.
1120
____
1221

13-
== File Map
22+
Every source file opens with `declare(strict_types=1)`. The `Validator` class
23+
(`src/Validator.php`) uses only PHP built-ins — `filter_var`, `preg_match`,
24+
`parse_url` — with no Composer runtime dependencies. `Sanitizer::html()` calls
25+
`htmlspecialchars($input, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8')` with explicit
26+
charset enforcement. `Sanitizer::js()` escapes to Unicode escape sequences
27+
(`\uXXXX`) for characters outside the safe printable ASCII set. `Sanitizer::css()`
28+
strips everything outside alphanumeric and safe CSS punctuation. The `Headers`
29+
class (`src/Headers.php`) calls PHP's `header()` function and `Headers::secure()`
30+
is a single-call method that sets CSP, HSTS, X-Frame-Options, Referrer-Policy,
31+
Permissions-Policy, and removes `X-Powered-By` and `Server` headers in one
32+
invocation.
33+
34+
**Caveat:** "Zero dependencies" applies to the runtime library. The dev toolchain
35+
(PHPUnit, PHPStan, php-cs-fixer) are Composer dev-dependencies. The library does
36+
not handle SQL injection prevention (use PDO prepared statements), CSRF (use
37+
framework tokens), authentication, or encryption — these are explicit non-goals
38+
documented in the README's "What php-aegis Does NOT Do" section.
39+
40+
- Validator: `src/Validator.php`
41+
- Sanitizer: `src/Sanitizer.php`
42+
- Headers: `src/Headers.php`
43+
- Tests: `tests/` (PHPUnit)
44+
45+
== Claim: RDF/Turtle escaping — a unique differentiator with no other PHP library equivalent
46+
47+
[quote, README]
48+
____
49+
RDF/Turtle Escaping — unique W3C-compliant semantic web security (no other PHP
50+
lib does this). Best for: Semantic web applications (RDF/Turtle escaping —
51+
unique to php-aegis).
52+
____
53+
54+
`TurtleEscaper` (`src/TurtleEscaper.php`) implements W3C Turtle 1.1 string and
55+
IRI escaping. `TurtleEscaper::string()` escapes the characters required by the
56+
Turtle grammar: backslash, double-quote, newlines, carriage returns, tabs, and
57+
the extended escape sequences `\t \b \n \r \f`. `TurtleEscaper::iri()` validates
58+
IRI structure and percent-encodes characters that are invalid in IRIs.
59+
`TurtleEscaper::literal()` wraps a string in Turtle literal syntax with optional
60+
language tag (`"value"@en`) or datatype (`"value"^^xsd:type`).
61+
`TurtleEscaper::triple()` builds a complete subject-predicate-object triple
62+
string ending with ` .`. Without this escaping, user-supplied strings injected
63+
into Turtle documents would break the RDF serialisation or permit injection of
64+
arbitrary triples — a real attack surface in IndieWeb and Linked Data
65+
applications.
66+
67+
**Caveat:** The IndieWeb integration work (Micropub, IndieAuth, Webmention
68+
helpers) is on the roadmap but not yet complete. The `src/IndieWeb/` directory
69+
exists but implementation and validation depth are noted in the README as needing
70+
to catch up to the design documentation.
71+
72+
- Implementation: `src/TurtleEscaper.php`
73+
- IndieWeb stubs: `src/IndieWeb/`
74+
- Related: `HANDOVER_SANCTIFY.md` (integration notes with sanctify-php)
75+
76+
== Dogfooded Across The Account
1477

1578
[cols="1,2"]
1679
|===
80+
| Technology | Also Used In
81+
82+
| **PHP 8.1+ security tooling** | https://github.com/hyperpolymath/sanctify-php[sanctify-php]
83+
(static analysis companion), https://github.com/hyperpolymath/proof-of-work[proof-of-work]
84+
(spam prevention), the NUJ and LCB websites (production PHP deployments)
85+
| **WordPress adapter pattern** | `src/WordPress/` adapter (23 functions + MU-plugin)
86+
mirrors the adapter architecture in https://github.com/hyperpolymath/project-wharf[project-wharf]
87+
(`adapters/wordpress-wharf/`)
88+
| **Semantic web / RDF** | RDF tooling appears in
89+
https://github.com/hyperpolymath/rrecord-verity[rrecord-verity] and the
90+
IndieWeb stack across the account
91+
| **PHPStan + PHPUnit** | Standard PHP quality tooling in this repo and
92+
https://github.com/hyperpolymath/sanctify-php[sanctify-php]
93+
|===
94+
95+
== File Map
96+
97+
[cols="1,3"]
98+
|===
1799
| Path | What's There
18100

19-
| `src/` | Source code
20-
| `test(s)/` | Test suite
101+
| `src/Validator.php`
102+
| Input validation. All methods static. Covers: email, URL, HTTPS-URL, IPv4,
103+
IPv6, UUID, slug, JSON, integer (with range), domain, hostname, semver,
104+
ISO 8601, hex colour, null-byte detection, safe filename check, printable-ASCII
105+
check. Uses `filter_var` and `preg_match` with no external deps.
106+
107+
| `src/Sanitizer.php`
108+
| Context-aware output escaping. All methods static. Contexts: HTML
109+
(`htmlspecialchars` + UTF-8), JS (Unicode escape sequences), CSS (allowlist
110+
chars only), URL (`rawurlencode`), JSON (`json_encode` with flags), filename
111+
(strip path separators and null bytes).
112+
113+
| `src/Headers.php`
114+
| Security headers. `Headers::secure()` is the single-call hardening method.
115+
Individual methods: `contentSecurityPolicy()`, `strictTransportSecurity()`,
116+
`frameOptions()`, `referrerPolicy()`, `permissionsPolicy()`,
117+
`removeInsecureHeaders()`.
118+
119+
| `src/TurtleEscaper.php`
120+
| W3C Turtle 1.1 escaping. Methods: `string()`, `iri()`, `literal()`,
121+
`triple()`. Unique in the PHP ecosystem.
122+
123+
| `src/IndieWeb/`
124+
| IndieWeb helpers (Micropub, IndieAuth, Webmention). Partially implemented.
125+
126+
| `src/RateLimit/`
127+
| Rate limiting (documented in roadmap; not yet release-complete).
128+
129+
| `src/WordPress/`
130+
| WordPress integration: 23 adapter functions and an MU-plugin for drop-in
131+
use in WordPress environments.
132+
133+
| `composer.json`
134+
| Project manifest. `require` section is empty (zero runtime deps).
135+
`require-dev`: phpunit, phpstan, php-cs-fixer.
136+
137+
| `phpstan.neon`
138+
| PHPStan configuration. Level 8 (strict) analysis.
139+
140+
| `phpunit.xml`
141+
| PHPUnit test configuration.
142+
143+
| `manifests/`
144+
| Container and deployment manifests.
145+
146+
| `docs/`
147+
| Design documents, positioning guide, validation findings.
148+
149+
| `PRIORITY.adoc`
150+
| Ordered list of remaining work before public release.
151+
152+
| `HANDOVER_SANCTIFY.md`
153+
| Integration guide for teams using both php-aegis and sanctify-php.
154+
155+
| `PHP_AEGIS_ANALYSIS_SUMMARY.md`
156+
| Analysis summary of current feature completeness.
157+
158+
| `PHP_AEGIS_DEVELOPMENT_PLAN.md`
159+
| Development plan with phase milestones.
160+
161+
| `validation/FINDINGS-AND-RECOMMENDATIONS.md`
162+
| Validation evidence document. Use alongside `PRIORITY.adoc` to judge
163+
release readiness.
164+
165+
| `.machine_readable/6a2/`
166+
| A2ML checkpoint files: STATE, META, ECOSYSTEM, AGENTIC, NEUROSYM, PLAYBOOK.
21167
|===
22168

23-
== Questions?
169+
== Checking It
170+
171+
[source,bash]
172+
----
173+
# Install dev deps
174+
composer install
175+
176+
# Run tests
177+
just test
178+
# or: vendor/bin/phpunit
179+
180+
# Static analysis (PHPStan level 8)
181+
just analyze
182+
# or: vendor/bin/phpstan analyse src
183+
184+
# Check code style
185+
just lint
186+
# or: vendor/bin/php-cs-fixer fix --dry-run
187+
----
188+
189+
== Honest Status
24190

25-
Open an issue or reach out directly — happy to explain anything in more detail.
191+
v0.1.1 is feature-complete for the core: validation, sanitization, headers,
192+
and Turtle escaping. The remaining work before a public Packagist release
193+
is concentrated in test completeness, publication validation evidence, and
194+
the IndieWeb/rate-limiting roadmap items. See `PRIORITY.adoc` for the
195+
ordered task list and `validation/FINDINGS-AND-RECOMMENDATIONS.md` for the
196+
evidence gap analysis.

0 commit comments

Comments
 (0)