DevOps Engineer
Aryan is a cloud infrastructure and DevOps enthusiast with a sharp focus on cloud cost optimization and automating complex, manual workflows across AWS and Azure.
Every DevOps team knows this queue. "Please add an environment variable to the staging config." "Can you bump this value in prod?" "I need access to this database." Each request is small, safe in isolation, and completely blocking for the developer who raised it. Each one is also a ticket, a context switch, and fifteen minutes of an engineer's attention spent on work a machine should do.
When we measured our own queue over the last two quarters, the shape was striking. 41% of all tickets reaching the platform team were environment-variable updates. Another 38% were access-provisioning requests: databases, developer tooling, CI. Two repetitive, rule-based categories that together made up 79% of our total ticket workload.
Today, that 79% no longer exists as tickets. Developers serve themselves through the Self-Service Portal for Developers we built for exactly this class of work. When a human is needed at all, it is a Team Lead or platform admin tapping Approve on a Slack message. Nobody on DevOps runs a command.
The easy version of this project is a web form that calls AWS with a powerful service role. That version gets vetoed in the first security review, and it should be. A portal that holds broad credentials is a privilege-escalation bridge: whoever compromises the portal, or finds one missing if statement in it, inherits everything the portal can do.
So we set a constraint before writing any code: the portal must be safer than the manual process it replaces, not just faster. A DevOps engineer handling a ticket by hand applies judgment about scope. Our system had to encode that judgment into boundaries that hold even if the application code is wrong.
That constraint produced three pillars:
The rest of this post walks through each pillar in the order a request experiences them.
The portal is a FastAPI application living in a dedicated operations AWS account, deliberately separated from the accounts that hold the actual configuration. It is fronted by a private, VPC-internal elastic load balancer, reachable only over the corporate VPN. Sign-in runs over SAML through CloudKeeper Prism, the centralized single sign-on product we’ve built for teams looking to simplify this task. And it runs at CloudKeeper, the same login our engineers already use for every internal tool, so the portal never handles a password. There is no public ingress at all.

Three design choices in this diagram carry most of the security weight:
This is the idea the whole system rests on.
The cross-account AWS IAM roles the portal assumes are intentionally coarse. The non-prod read role, for example, grants read on parameter/cln/*, the entire configuration namespace. If the boundary stopped there, the portal would effectively hold the keys to everything.
It does not stop there, because AWS lets you attach an inline session policy at AssumeRole time, and the effective permissions of the session are the intersection of the role's policy and the session policy. The session can only ever be narrower than the role. So on every single request, the portal computes a one-off policy scoped to exactly the environment and service the user is operating on:
The credentials returned by STS for this session cannot read /cln/dev/payments-api/*or anything else, no matter what the application code requests afterward. If a bug (or an attacker) tricks the portal into requesting the wrong path, AWS itself returns an AccessDenied response. The enforcement lives in the cloud provider, below our code, which is precisely where you want your last line of defense.
For production writes, we narrow even further. An approved prod change is applied with a session policy scoped to one exact parameter key, not a wildcard:
A few more properties of every assumed session:
Just as important is the role split. We use four distinct roles instead of one:
The prod apply lane physically cannot delete a parameter; the capability is absent from the role itself. And because bypass actions run under a different role ARN, they produce a visibly distinct signal in AWS CloudTrail. Anyone reviewing logs can separate "the normal approval pipeline did this" from "an admin overrode the process" without parsing application logs.
The session policy is the last wall, not the only one. A request that reaches STS has already survived five checks, each one enforced server-side:

The philosophy: the UI is never the control. Every layer that matters answers at the API, and the layer that matters most answers inside AWS itself.
Boundaries alone don't remove tickets; they make it safe to remove tickets. The second half of the story is an approval flow fast enough that nobody misses the old queue.
Routine work flows freely; anything with a blast radius gets exactly one human, and that human is the person accountable for the service, not a central DevOps queue.
The mechanics matter, so here is the full lifecycle of a prod change:
Four deliberate decisions live in that diagram:
The result, from the approver's chair: a card appears in Slack with who, what, where, and old versus new value. They tap Approve, confirm, and are done. That is the entire remaining DevOps involvement in what used to be a ticket.
SOC2 evidence questions reduce to: who did what, to which resource, when, and what was the outcome? We answer at two independent layers.
Layer 1: an append-only application audit table. Every action writes a record to a DynamoDB table that the application only ever inserts into; there is no update or delete path in code. A single record carries the full business context:

Details worth stealing:
Layer 2: CloudTrail, with a join key. The application table says what the portal intended; CloudTrail records what actually happened inside AWS, written by the platform rather than by our code. The two layers meet at the RoleSessionName. Because every assumed session is named ck-{action}-{user}-{epoch} (or ck-approval-{id} for approval applies), every PutParameter event in the workload account's CloudTrail carries the acting portal user or approval in its identity block. An investigator can start from an AWS CloudTrail event and land on the exact portal request, with its approver and diff, in seconds, or start from an audit row and confirm AWS saw exactly that call and nothing more.
Neither layer trusts the other, and that is the point. Application logs alone can be doubted ("the app could write anything"); CloudTrail alone lacks business context ("a role wrote a parameter, but on whose behalf, and who approved?"). Together, with a shared key, they close the loop.
The numbers moved the way we hoped. Environment-variable changes, 41% of the platform team's ticket workload over the last two quarters, went fully self-service on day one. Access provisioning for databases, developer tooling, and CI, another 38% of the workload, flowed through the same approval-gated architecture. Together, that is 79% of our total ticket workload, automated end to end.
The remaining 21% is the roadmap, not the residue. The next targets are service-setup automation, so that standing up a new service becomes a portal flow rather than a project, and AI-powered debugging summaries for deployment failures, so that even the tickets we cannot eliminate arrive pre-diagnosed rather than raw.
Just as telling is what DevOps involvement looks like now. For the majority of requests: nothing. For the rest: a Slack card and one click by the person who owns the affected service. The platform team's role shifted from executing changes to defining policy: which team owns which service, which modules each team can use, and where approval is required. The system executes.
And because every boundary is structural, the usual anxiety of self-service, "what if someone finds a way around it?", has a concrete answer: around it to where? The credentials in play at any moment cannot reach past a single service path; prod writes cannot happen without an approval row and cannot delete anything, and both AWS and the portal are independently writing down everything that occurs.
Three principles from this build that transfer to any internal platform touching cloud resources:
None of this required exotic technology: STS, DynamoDB, Slack, and a strict habit of asking "what enforces this if the code is wrong?" The 79% was the reward for answering that question at every layer.