I build and operate the platform that backend services run on: infrastructure as code, deployment, observability, cost, and security. I come from backend engineering, so I work on both sides of that line.
Platform Engineer & DevOps · 2026-06 – present
- Infrastructure platform — brought a console-built AWS environment under Terraform with OIDC-based workflows
- Observability — monitoring managed as code, alerting moved to SLOs
- Deploy & cost — improved the internal deployment pipeline (blue-green); traced where the cloud bill comes from and cut it
- Security — default-deny authorization, column-level encryption of personal data, ISO 27001 / ISMS-P preparation
TeamBind · Backend Engineer / CTO · 2025-07 – 2026-06
A space-booking and community platform for musicians
- Designed and built a microservices architecture as the sole backend engineer
- Built and operated a self-managed (on-premises) Kubernetes cluster, including incident response
- Designed database schemas and data models for core services
- Developed web and app backends end to end
| Primary | |
| Comfortable |
- OpenTelemetry Java instrumentation — GHSA-9pmw-7q9q-j3jc: Reported a SQL sanitization flaw that could expose sensitive string literals in span attributes; credited as the reporter. Fixed in Java agent 2.33.0.
| Project | Contributions |
|---|---|
| Flux pkg/ssa |
#1377 Added an optional callback that reports ownership conflicts from SSA’s existing object lookup, allowing controllers to warn before applying a resource without an extra API request |
| OpenTelemetry Java instrumentation |
• #20845 Fixed the agent no longer propagating context through Reactor operators after the application calls Hooks.resetOnEachOperator(), which broke the context of externally driven Flux.create subscribers• #20659 Fixed @WithSpan on a Flux requesting 32 elements from the source regardless of downstream demand, which dropped queued work on cancel• #20658 Fixed Spring Kafka listeners with async acks or async return types emitting a duplicate Kafka client process span per record (a 2.32.0 regression) • #20660 Fixed MySQL/MariaDB address=(host=..)(port=..) JDBC URLs without a subprotocol losing server.address/server.port• #20661 Fixed the Lettuce library reporting the command name (e.g. BLPOP.) as error.type on client-side timeouts |
| Spinnaker Orca |
• #8174 Fixed a race where a duplicate StartExecution delivery could move a completed pipeline back to RUNNING, using a conditional status update (SELECT ... FOR UPDATE)• #8208 Made StartExecution's rollback after a failed StartStage push conditional, so a cancel made in that window is no longer overwritten and the redelivered message doesn't start the canceled pipeline (reproduced against MySQL)• #8209 Added a test that depends on the row lock in updateStatusIfExpected; it fails if SELECT ... FOR UPDATE is removed |
| Debezium | • #8220 Fixed a regression in the generated MySQL DDL grammar where ALTER DATABASE without a database name failed to parse and stopped the connector• #8225 Fixed the MariaDB and legacy MySQL grammars taking DEFAULT as a database name in ALTER DATABASE DEFAULT CHARSET ..., which silently skipped the charset change (follow-up requested by the maintainer) |
| ANTLR grammars-v4 | • #5037 Made the schema name optional in the MySQL alterDatabase rule, the upstream source of the Debezium grammar fixed in #8220• #5039 Fixed the MariaDB grammar taking DEFAULT as the database name in ALTER DATABASE DEFAULT CHARSET ..., upstream of one of the two grammars fixed in #8225 (the other, Positive-Technologies, is deprecated upstream and not accepting fixes) |
| Keycloak | #53990 Fixed AccessTokenContext validating grantType twice instead of rawTokenId, so a null token id reached the encoded token id as the literal null rather than failing at construction |
| Lettuce Redis Java client |
• #3952 Fixed DefaultEndpoint validating clientOptions twice so a null clientResources bypassed the null check and surfaced later as an NPE away from the construction site• #3955 Fixed assertion messages that named the wrong argument: a misspelled ReauthenticateBehavior in a public builder, and CompressionCodec reporting a null output stream as the input• #3954 Fixed typos in the Javadoc of the stream XACK and XLEN commands across every API flavor, plus other comment typos |
| Spring Cloud Config | #3342 Expired the Git refresh rate when /monitor receives a webhook, so refreshed applications get the new commit |
| Spring Security | #18855 Applied the javadoc-warnings-error policy to the spring-security-aspects module, aligning it with the rest of the build |
| Micrometer | #7256 Documented Jakarta Mail instrumentation and registered it in the Observation instrumented-projects reference |
| Project | Contributions |
|---|---|
| Flux kustomize-controller |
#1807 Add warning events when a Kustomization overwrites resources owned by another Kustomization, making silent ownership conflicts visible |
I write up what I learn on my blog: SRE and observability, IaC work logs, incident response and more (180+ posts).