Work

Three engagements, anonymised. Specifics on request, where contracts allow.

One sign-on for several hundred websites

Web platform operator · Keycloak · remote, part-time

The problem

The operator ran several hundred web properties and needed single sign-on across all of them. There was no shared identity layer to extend. It had to be built from scratch, as one platform for the whole estate.

Constraints

  • One engineer. I was the only identity engineer on the account: architecture, build and incident response.
  • Part-time. The work fitted a fixed weekly budget, alongside a full-time job.
  • Keycloak out of the box was not enough. The standard configuration did not cover everything the platform needed.

What I built

A Keycloak SSO platform serving the whole estate, up to 10,000 end users.

Three custom extensions, written in Java, where configuration stopped:

  • A registration flow, for direct sign-up and for social login, that validates names and generates a unique username for each new account.
  • Themes for the login pages and the emails, responsive and with dark mode.
  • An event listener that mirrors new and verified users into the operator’s membership system, so both systems agree on who exists.

Then the upkeep. I took the platform through three major Keycloak version upgrades. Each ran blue/green: a parallel cluster on the new version, then a switch of traffic, so the running platform was never upgraded in place.

I still maintain the platform part-time. Recent changes, such as the email verification flow, are made with Claude Code.

Result

  • Users sign in once and are signed in across several hundred properties.
  • Three major upgrades, each with under 5 minutes of user-facing downtime.
  • One person ran all of it, part-time.

Moving identity out of a monolith without users noticing

SaaS company · Keycloak, OpenFGA, Kafka · remote, part-time

The problem

Authentication, roles and permissions lived inside the company’s monolith. Any change to who could sign in, or what they could do, meant a change to the monolith. That made every access rule expensive, and it blocked splitting the monolith up.

Constraints

  • No planned downtime.
  • The legacy system had to keep working, with as little change to it as possible.
  • Users, roles, permissions and objects had to move without anyone noticing.
  • Access differs per customer organisation. A user can hold different rights in different tenants, which plain role checks do not express.
  • Remote and part-time.

What I built

A new IAM on Keycloak, replacing the in-house authentication code, for 10,000+ users. The identity service is event-driven: an API takes user lifecycle requests and publishes them to Kafka (Avro, with a schema registry), and a consumer applies them to Keycloak and OpenFGA and publishes the result. Existing users were moved from the legacy database into Keycloak with an import tool.

A central authorization model on OpenFGA. Roles, permissions and objects were extracted from the monolith into Keycloak and OpenFGA. The model expresses per-organisation access: what a user may do depends on the organisation they are acting in. It replaced role checks scattered through the code with one place that answers “who can do what”.

The start of the monolith split. Three services were extracted over 6–12 months, again with no planned downtime.

Cloud cost. Rightsizing, and optimising applications and data processing, took cloud spend down by around 10–15%.

Result

  • 10,000+ users moved to Keycloak with no planned downtime.
  • One authorization model in place of scattered role checks.
  • Three services out of the monolith.
  • Cloud spend down by around 10–15%.

Getting a team’s codebase ready for coding agents

Norwegian ERP software company · Claude Code, MCP · remote, part-time, as AI consultant

The problem

The team builds an ERP and accounting product across many repositories: a Java and Spring Boot back end, an Angular front end, shared libraries and infrastructure. The coding agents the developers used did not know the team’s conventions, and the specs lived in Jira and Confluence, out of the agents’ reach.

Constraints

  • Many repositories, one workflow. The repositories are held together as submodules of one superrepo, and the workflow had to work from there and from each repository on its own.
  • The conventions live in Confluence and keep changing. Agent instructions had to follow them, not fork them.
  • Secrets stay out of what the agent reads.
  • Remote and part-time.

What I built

A spec-driven workflow. Before the agent implements a ticket, it reads the spec from Jira through the Atlassian MCP server, and it keeps the ticket updated while it works. A start-ticket skill kicks off the work from the spec.

Instructions per repository. Each repository has a CLAUDE.md that links the Confluence conventions it follows, and a rule that every merge request updates it when the repository changes.

Skills and hooks. A naming-convention check and a standards review, as skills. Hooks that work from any path and never push submodule updates to main.

Agent-safe repositories. Environment files untracked and ignored, hardcoded credentials in compose files parameterised, the secrets conventions brought in line with Confluence, and agent feedback sharing switched off.

Result

  • The team works through the workflow day to day.
  • Specs, conventions and tickets reach the agent from the tools the team already uses.

Have a similar problem?

[email protected]