Proof · Notes
Engineering notes
Practical engineering notes on continuous integration (CI), identity and access, browser behavior, tenant isolation, and the systems behind Yellow Theme’s own intake and evidence vault. Examples use stand-in values and synthetic data; no client systems or names appear.
- CI workflow — Semgrep, npm audit, and gitleaks.
- Storage policy — a CC6.1 deny, with tests.
- Evidence index — control ID to the workflow and the export.
21 write-ups
Start here
Three notes that show the judgment before the reverse-chron list: wrong green, tenant isolation, and the session boundary.
-
Wrong green
An empty matrix is not a green board
A control board can look finished with zero approved statements. Green only means approved wording is present — and status still starts unset.
-
Evidence vault
Isolate tenants without creating a bucket for each one
Bind object keys to the tenant, return the same response for missing and unauthorized data, and use a separate encryption key per tenant on the shared bucket.
-
Session boundary
An HttpOnly cookie cannot help if the API returns the refresh token
Keep refresh tokens behind the server boundary. If the session endpoint echoes one into JSON, browser script—and any successful XSS—can still steal the long-lived credential and own the session.
All notes
-
2026-10-06
Config defines NetScaler blast radius
CVE-2026-88779 is a CVSS 8.7 memory overflow on NetScaler ADC/Gateway — only when the box is a SAML SP or IdP. Patch pins first; availability-only per Citrix.
-
2026-10-04
The pack carries the brief label, not a sixth rung
When an evidence pack prints a bare stage number, readers invent a new rung. Keep numbers in data; show the plain-language delivery label.
-
2026-10-04
An empty matrix is not a green board
A control board can look finished with zero approved statements. Green only means approved wording is present — and status still starts unset.
-
2026-10-03
An empty answer is not a yes
A blank field is not evidence. Count yes only when the text already says yes — leave unknown unset, never fill gaps with guesses.
-
2026-10-03
The password form is ours
Native password stays on our login form. The hosted login page is only for Google handoff — do not rebuild hosted as a password form.
-
2026-10-03
A strict content-security policy never runs an inline theme boot
A strict CSP with script-src 'self' blocks an inline theme boot. Put the theme class on the static HTML — do not loosen script-src for first paint.
-
2026-09-26
The path carries the API version
Put the major version in the URL. Keep OpenAPI info.version aligned. The contract lives under /v1 only — bare aliases are gone (webhooks excepted).
-
2026-09-18
Contacts are not weekly counters
People and deals belong in the CRM. Weekly counters stay on the event store that recorded them.
-
2026-09-17
Reader Mode dropped the FAQ answers
Questions stored only inside buttons and lists with no visible list semantics can disappear from reading tools. Keep the words in headings, paragraphs, and real lists.
-
2026-09-15
Keep SSH closed until break-glass access is needed
Default the allowed CIDR list to empty so port 22 is not exposed. Use console-based access or open a temporary CIDR only when necessary.
-
2026-09-15
Hosted login cannot carry the full legal footer
A hosted login page can link Privacy and Terms. Put Security, Access help, and the agreement sentence on surfaces you control.
-
2026-09-15
A URL beginning with // is not same-origin
A protocol-relative URL starts with a slash but can point to another host. Reject double-slash links before allowing root-relative paths.
-
2026-09-15
An HttpOnly cookie cannot help if the API returns the refresh token
Keep refresh tokens behind the server boundary. If the session endpoint echoes one into JSON, browser script—and any successful XSS—can still steal the long-lived credential and own the session.
-
2026-09-15
WAF did not protect the raw Function URL
WAF only sees requests that pass through CloudFront. Require an origin secret at the function so direct calls to the public URL fail closed.
-
2026-09-13
A red job is not proof that a secret scan ran
A red CI job can mean “license missing,” not “scan found a secret.” Require the CLI — and make fixtures fail for the right reason.
-
2026-09-12
The form does not decide truth
The server names the package from a stable id and ignores the browser title. A retry with the same token returns the first answer.
-
2026-09-12
Put the query string before the URL fragment
Anything after # is a fragment, not a query string. For a prefilled anchored form, write /?key=value#form, not /#form?key=value.
-
2026-09-03
Isolate tenants without creating a bucket for each one
Bind object keys to the tenant, return the same response for missing and unauthorized data, and use a separate encryption key per tenant on the shared bucket.
-
2026-09-03
Why authenticated downloads lose their file extensions
JavaScript cannot read Content-Disposition across origins unless CORS exposes it. When that header disappears, the UI guesses a filename—and usually drops the extension.
-
2026-09-03
Give API Gateway a hostname you control
Use API Gateway’s custom-domain target for DNS. Pointing your CNAME at the API ID hostname presents the wrong TLS certificate.
-
2026-09-03
Put CloudFront and WAF in front of Lambda Function URLs
AWS WAF cannot attach directly to a Lambda Function URL. Use CloudFront, a CloudFront-scoped web ACL in us-east-1, and a hostname you control.
Prefer primary sources? See our curated insights reading list. How we deliver: methodology.