PAUL MK
■ 0 KB JavaScript shippeddefault-src 'none'script-src 'none'securityheaders.com A+Mozilla Observatory A+verify below ↓

Software engineering · Application security · Nairobi, Kenya

I break applications and then ship the fix.

Software engineer first, pentester second, AppSec by consequence.

Self-taught engineer. I ship production Python/FastAPI, Go and TypeScript, then attack it across tenant boundaries, payment webhooks and authorization paths. Everything on this page is a diagram, a diff or a rule — not a claim.

Four operational systems, ~120,000 lines, built solo. One at pre-pilot, none yet in production — each one with its status.

Available now — full-time roles and short engagements.

Backend, platform and DevSecOps roles, and multi-tenant authorization and payment integration reviews.

Remote, or on-site in Nairobi · UTC+3 — full overlap with UK and EU hours, mornings only with the US west coast

Capabilitybuild ⇄ break
What I build and what I attack, by layer of the stack
LayerI shipI attack
APIFastAPI, Go servicesIDOR, mass assignment
AuthRoles, capabilities, scopingHorizontal + vertical escalation
DataPostgreSQL, RedisCross-tenant reads
PaymentsWebhooks, ledgerReplay, idempotency
ClientReact / TypeScriptDOM XSS, CSP gaps
CI / InfraDocker, AWS, ActionsSemgrep rules in CI

AppSec job postings · 5,197 postings · 796 companies · Oct 2025 – May 2026

need real engineering ability
60.6%
open to entry level
1.9%

Pixee Research, The State of AppSec Hiring 2026, May 2026. Not my sample — someone else's, and linked so you can check the method.

Projects — three, each carrying its artifact

All projects →

ParkSense

pre-pilot

A commercial parking platform: cameras read plates at the gate, an on-site Go agent runs the lane through network loss, drivers pay by M-Pesa on exit straight to the operator’s own till, and a barrier opens on a dry contact. Multi-tenant, with an operator console, an admin console, guard and driver apps, permits, enforcement, reconciliation and subscription billing. Roughly 36,000 lines, built solo.

UNTRUSTEDAPP ZONEDATA / OTagentFastAPItenant scopePostgresbarrier

Python · FastAPI · SQLAlchemy async · PostgreSQL/TimescaleDB · Go · React/TS · Docker

Kartly

48 tests

A regression harness for 24 web vulnerability classes. Each class is proven in both directions by code: an exploit test that expects the attack to succeed on main, and a fixed test that reuses the same attack code and expects it to be refused on the class’s fix branch. 48 tests in two suites.

■ 3 fix + rule■ 21 fix, rule pending

TypeScript · Node/Express · Prisma · Docker

Semgrep rules

4 rules

Custom JS/TS rules for unscoped lookups, mass assignment, path traversal and fail-open error handling, grouped by OWASP category with a test fixture sitting beside every rule.

const order = await db.order.findUnique({
where: { id },
const order = await db.order.findFirst({
where: { id, tenantId: ctx.tenantId },
})

rule: unscoped-lookup-by-user-id · a01-broken-access-control

YAML · Semgrep · JS fixtures · GitHub Actions

Stack — and where each part is proven

Check any of it →

A list of language names is a thing anyone can write in thirty seconds, and every reader knows it. So each row below names the artifact and a number you could check rather than the language on its own.

Languages and technologies, each with the project that demonstrates it and a measurable figure
LanguageWhere it is usedEvidence
PythonParkSense API — FastAPI, SQLAlchemy async, Alembic196 files · ~29,700 lines · 486 passing tests
GoParkSense edge agent — offline queue, RTSP capture, TCP ingest, relay watchdog37 files · ~6,200 lines · build and vet clean
TypeScriptKartly — Node, Express, Prisma. Also the ParkSense React consoles.128 files · ~4,100 lines · 48 tests proving 24 bug classes both ways
SQLPostgreSQL and TimescaleDB — the ParkSense schema and its migrations19 migrations, single head, round-trip verified
Semgrep / YAMLA published rule pack for the bug classes I keep finding4 rules · 4 fixtures · tested in CI on every push
Astro / CSSThis site — no framework, no client JavaScript, one external stylesheet16 pages and components · 0 KB of JavaScript shipped

Services — fixed scope, fixed price

All services →

Multi-tenant isolation audit

Every endpoint tested across tenant boundaries — same role, different organisation. The failure mode scanners are blind to and most pentests never reach.

Receive
Findings report — reproduction steps, severity, and the fix as a diff. One retest.
Timeline
5 business days, plus one retest within 30 days
From
USD 5,000

Payment integration security review

Signature verification and whether the comparison is constant-time, replay protection, idempotency claimed atomically under concurrent delivery, settlement races, credential handling.

Receive
Findings report plus a reconciliation gap analysis. One retest.
Timeline
4 business days, plus one retest within 30 days
From
USD 5,000

Writing

Technical write-ups on access control, payment integration failure modes, and turning findings into Semgrep rules.

Go to writing →

This page's own posture✓ enforced, not report-only
Content Security Policy directives served by this site and why each one is present
default-src 'none'Nothing loads unless a directive below allows it.
script-src 'none'No script executes, so this page cannot have DOM XSS.
style-src 'self'One first-party stylesheet. No inline style, no CDN.
img-src 'self' data:Diagrams are inline SVG; no third party sees your request.
font-src 'self'System faces only; nothing fetched from Google Fonts.
base-uri 'none'Base-tag injection cannot rewrite relative URLs.
frame-ancestors 'none'The page cannot be framed, so it cannot be clickjacked.

securityheaders.com

A+

Mozilla Observatory

A+

JS shipped

0 KB