# Full Technical Corpus: Akshay Kr Gupta > Designing enterprise systems for regulated environments - where architecture, AI, and governance intersect. > URL: https://akshaykgupta.me --- # Digital India Runs on OTPs - URL: https://akshaykgupta.me/blog/digital-india-runs-on-otps/ - Author: Akshay K Gupta - Published: Jul 22, 2026 - Tags: india, otp, sms, authentication, cyber-security, enterprise-architecture - Description: India's digital economy runs on billions of SMS messages every day. Explore the architecture, reliability challenges, and future of OTP authentication Before you even step out of bed, the protocol has already started. First thing in the morning, the quick-commerce delivery executive rings your doorbell with your groceries. You open the door, and almost instinctively, he asks, “Sir, 4-digit delivery PIN?” Next, you get into a cab and, before your ride starts, the driver looks back and says, “Sir, OTP.” By afternoon, you may have already approved a credit card transaction, completed an Aadhaar e-Sign for any government-related service, or logged into a SaaS application, using another six-digit code. By evening, there may be a few more waiting for you: an e-commerce delivery, a food order, a banking transaction, perhaps another login. None of this feels unusual anymore. And that is precisely what makes it interesting. For the average urban digital consumer in India, the OTP is no longer an occasional security checkpoint. It has become part of the invisible operating rhythm of everyday digital life. We don't think about the systems that generate it, route it, filter it, deliver it, expire it and validate it. We simply expect the six digits to appear on our phone within a few seconds. And when they don't, we immediately notice. ## The scale behind six digits To understand why this matters, it helps to step back from the individual OTP and look at the infrastructure underneath it. India's digital economy has created an enormous Application-to-Person, or A2P, messaging ecosystem. Banks, fintech companies, e-commerce platforms, airlines, government services, logistics companies, SaaS providers and thousands of other businesses use SMS to communicate transactional and authentication events to customers. Industry estimates have put India's commercial SMS traffic at well over a billion messages a day, with some estimates placing it around 1.8 billion or more. At that scale, we're no longer talking about “sending an SMS.” We're talking about operating a national-scale distributed messaging system. Put that number into perspective: **1.8 billion messages a day is roughly 75 million messages an hour, or more than 1.2 million messages every minute.** That is more than 20,000 messages every second, averaged across the day. And OTPs are only one part of that traffic. The system is simultaneously handling transaction alerts, delivery notifications, account updates, promotional messages, government communications and other service messages. India's telecom ecosystem also has a substantial regulatory and compliance layer around this traffic: businesses sending bulk communications have to register as principal entities, register headers and templates, and comply with the country's DLT-based framework. The important point isn't whether the exact number on a particular day is 1.3 billion, 1.8 billion or higher. The important point is the order of magnitude. **Millions of messages are moving through the ecosystem every minute.** And this is where the architecture starts to creak. ## The paradox underneath the OTP We have built a 21st-century digital economy on a **1990s-era telecommunications protocol**. The technical foundations of SMS were designed during the late 1980s and early 1990s. It was an elegant solution for its time: lightweight, ubiquitous and capable of working across mobile networks without requiring an internet connection or a sophisticated application. Those characteristics are exactly why SMS has survived. But the world around it has changed dramatically. We now expect authentication to be near-instantaneous. We expect APIs to respond in milliseconds. We design cloud systems around P99 latency. We build globally distributed databases, event-driven architectures and real-time payment systems. And yet, for a huge number of digital interactions, the final authorisation step still looks like this: **Generate six digits → send a text message → wait for a telecom network → read the message → type the digits → verify.** That mismatch between modern application expectations and an old delivery primitive is where some interesting engineering problems begin to appear. ## When the OTP arrives late Consider a completely ordinary login. You enter your username and password. The application generates an OTP and starts a 60-second countdown. Ten seconds pass. Nothing. Twenty seconds. Still nothing. Thirty seconds. You press **Resend OTP**. A new code is generated. Then, perhaps ten seconds later, your phone finally buzzes. You enter the code. **Invalid OTP.** What happened? It may not have been an authentication failure at all. It may have been a distributed-systems problem. The first OTP was generated successfully, but the SMS was delayed somewhere in the delivery chain. You requested a second OTP, which generated a newer code. The messages then arrived in an order that the user did not expect. Now you have a race condition spanning multiple systems that you don't control. The application has state. The OTP service has state. The messaging provider has state. The telecom network has state. The handset has state. And all of those systems are communicating asynchronously. The user, however, experiences the entire thing as a single synchronous interaction: **“I requested an OTP. Why hasn't it arrived?”** This is one of the fundamental problems with SMS-based authentication. The underlying system is asynchronous, but the user experience is expected to feel synchronous. And when those two models diverge, the application doesn't get to explain the architecture to the user. The user simply concludes that the application is broken. ## The last mile is physical There is another problem that becomes obvious the moment you leave the comfort of a strong cellular network. Imagine you're trying to make a payment in a basement parking lot. Your phone is connected to Wi-Fi, the application loads perfectly and the payment request reaches the backend without a problem. Then the application asks for an OTP. No cellular signal. Or you're inside an elevator. Or in a crowded railway station. Or in a large building where mobile reception is poor. Or travelling through an area where the carrier network is congested. The application may be healthy. Your internet connection may be healthy. The payment infrastructure may be healthy. But the authentication channel has disappeared. That's an unusual architectural dependency. We can have an application running on highly available cloud infrastructure, with redundant databases, multiple availability zones and sophisticated observability—and still fail the user's transaction because a message didn't make it to a handset. This is an important distinction for anyone designing distributed systems: **Application availability is not the same as authentication availability.** ## The hidden system behind a six-digit code The simplicity of an OTP hides a surprisingly long chain of dependencies. A typical message can travel from an application through an authentication service and messaging provider, into telecom routing and filtering infrastructure, through the operator's messaging systems and signalling network, and finally across the radio network to the handset. India adds another interesting layer through its DLT-based commercial communications framework, which introduces sender registration, headers, templates and message traceability into the ecosystem. None of these components are inherently bad. In fact, many of them exist precisely because the ecosystem has to operate safely and at enormous scale. The problem is that every additional component introduces another place where latency, retries, filtering, routing or state synchronisation can affect the final user experience. This is why average latency can be a misleading metric for authentication. Suppose an OTP normally arrives in three seconds. That's great. But if a small percentage of messages take 30, 45 or 60 seconds, those tail events can become disproportionately important when the application itself has a one-minute authentication window. The user doesn't experience your average. **They experience their request.** And at India's scale, even a tiny percentage of problematic requests can represent a very large number of people. ## So, should we get rid of SMS OTPs? Probably not. And this is where the conversation becomes more nuanced. SMS has one enormous advantage that engineers sometimes underestimate: **the massive reach.** It works across a huge range of devices. It doesn't require the user to install an authenticator application. It doesn't require a modern smartphone. It doesn't require the user to understand public-key cryptography. And it doesn't depend on an internet connection in the same way that many app-based authentication mechanisms do. In a country as large and diverse as India, those characteristics matter. So the question isn't really: **“Why are we still using SMS?”** The better question is: **“Why are we using SMS for everything?”** SMS is a remarkably useful fallback and communication channel. It is a much less compelling default identity layer for every login, every transaction and every step-up authentication event. And that distinction changes the architecture. ## What comes next? The next generation of authentication is already moving in several directions. ### Passkeys: authentication without the message Passkeys, built on technologies such as FIDO2 and WebAuthn, replace the shared-secret model with public-key cryptography. Instead of sending a code to your phone and asking you to type it back, the device proves possession of a private key. The user may simply authenticate with Face ID, a fingerprint or the device's local security mechanism. There is no SMS to deliver. No message queue to wait on. No six-digit code to copy. And because the authentication is cryptographic rather than based on a shared code, the model is substantially more resistant to phishing and adversary-in-the-middle attacks. From an architecture perspective, this is an important shift: authentication no longer depends on a separate messaging system delivering a secret to a human. ### Network-based authentication Telecom networks are also becoming programmable. Initiatives such as **GSMA Open Gateway and CAMARA** are exposing standardised APIs that allow applications to interact with network capabilities in ways that were previously difficult or impossible. One direction this enables is silent verification based on network-level signals. Instead of asking a user to prove possession of a phone number by typing a code from an SMS, the application can potentially use trusted signals from the operator network to establish that the device, subscriber and session are consistent with what the application expects. The user doesn't have to do anything. And that is an important pattern in modern authentication: **Move verification from the human interaction layer into the infrastructure layer.** ### Device binding: the UPI pattern Another model that India has already demonstrated at enormous scale is device-bound authentication. The basic idea is simple: establish a cryptographic relationship between a trusted device and an identity, and use that relationship for subsequent authorisation. Instead of repeatedly asking, **“Can you read the code sent to this phone?”**, the system asks, **“Can this trusted device produce the cryptographic proof required for this transaction?”** That's a fundamentally different trust model. And importantly, the authentication event doesn't require generating and delivering a new SMS every time. ### Risk-based authentication Perhaps the biggest change, however, is conceptual. Why should every user perform the same authentication ceremony? Imagine logging into your bank from your usual phone, using your usual device, from a familiar location, with normal behavioural patterns. Now imagine a completely different situation: a new device, an unusual location, a high-value transaction and behaviour that doesn't match the user's normal profile. Those two situations should not necessarily receive the same amount of friction. Risk-based authentication takes this approach by evaluating context and asking for stronger proof when the situation warrants it. Low risk can remain almost invisible. High risk can trigger biometrics, passkeys or additional verification. For the user, that means less friction. For the business, it can mean better conversion. For the security team, it means concentrating controls where they actually provide value. ## The bigger architectural shift This isn't really a story about SMS. It is a story about **where we place trust**. The traditional model is roughly: **Application → SMS → Phone → Human → Application** The emerging model looks more like: **Application → Device / Network / Cryptographic Identity → Risk Decision** That is a fundamental shift. For decades, authentication has largely been designed around secrets that humans can possess and reproduce: passwords, PINs, codes and security questions. Modern systems are increasingly moving toward something different. Let the device prove possession. Let cryptography prove authenticity. Let the network provide context. Let risk engines determine how much additional verification is necessary. And let the human get involved only when the system actually needs them. This is the same broader evolution we've seen across infrastructure: from static credentials to short-lived credentials, from manually managed servers to automated infrastructure, and from synchronous assumptions to distributed systems designed around failure. Authentication is going through its own version of that transition. ## The architectural question for India There is still a difficult trade-off: **Universal reach versus deterministic security.** SMS won because it was universal. You didn't need a new application, a compatible biometric sensor or any understanding of public-key cryptography. You just needed a phone number. That advantage should not be dismissed. But as India's digital economy becomes more real-time, more automated and more dependent on digital identity, the cost of making SMS the default authentication layer becomes increasingly visible. Latency matters. Reliability matters. Fraud matters. Operational cost matters. And increasingly, user experience matters too. The next generation of authentication probably won't be about finding a faster way to deliver six digits. It will be about deciding when those six digits are necessary in the first place. ## The last OTP Perhaps the most interesting future is one where the OTP simply becomes less visible. You complete a payment without entering one. You sign a contract without waiting for one. You log into an application without typing one. You enter a building without reading one aloud. And you probably won't notice when the transition happens. That's the point. The best authentication experience is increasingly becoming the one that proves who you are **without asking you to prove it over and over again.** India has done something remarkable by making digital transactions and digital identity accessible to hundreds of millions of people. The next challenge is not simply to make that infrastructure faster. It is to make it **less dependent on a human reading six digits from a text message.** The OTP got us here. It may not be what takes us to the next stage. * * * ======================================== --- # Remember When OpenClaw Was The Future? - URL: https://akshaykgupta.me/blog/remember-when-openclaw-was-the-future/ - Author: Akshay K Gupta - Published: Jul 10, 2026 - Tags: openclaw, artificial-intelligence, software-development, ai-hype - Description: Five years from now, users won't care whether a feature uses an AI agent, MCP and RAG. They'll simply expect the software to work. Six months ago, it was almost impossible to scroll through LinkedIn or X without seeing someone talk about OpenClaw. People were buying Mac Minis specifically to run it 24×7. Every other post showed screenshots of autonomous agents. Some claimed their AI was managing emails, others said it was replacing entire workflows, and a few even suggested it was running parts of their business independently. If you only followed social media, you would have believed that autonomous AI agents had already arrived. Fast forward to today. Almost nobody is talking about OpenClaw anymore. Did it fail? Not really. Did everyone suddenly discover it was useless? No. The hype simply moved on. That observation made me realise something interesting, not about OpenClaw, but about the AI community itself. ## The AI Community Has an Incredibly Short Attention Span Over the past few years, I've noticed that almost every AI breakthrough follows the same lifecycle. Someone releases a new model, framework, protocol, or product. The internet reacts instantly. Within days, social media is flooded with screenshots, hot takes, tutorials, and bold predictions about how "everything has changed." Then the excitement peaks. Every podcast covers it. Every influencer posts about it. Every conference mentions it. Every developer feels they're already falling behind. Then, just as quickly as it appeared... Everyone starts talking about something else. The pattern is surprisingly consistent. > Week 1: "This changes everything." > > Week 3: "Everyone must use this." > > Week 8: "This is the future." > > Week 12: Everyone is talking about something else. > > Week 20: Serious developers are quietly using it every day. Notice something interesting? The final stage receives the least attention, despite being the one that actually matters. ## We've Seen This Before OpenClaw isn't unique. The same cycle has repeated itself with almost every major AI innovation. First it was prompt engineering. Then vector databases. Then RAG. Then local LLMs. Then AI agents. Then MCP. Then vibe coding. Each one dominated our feeds for weeks. People declared it the next revolution. Some declared it dead just a few months later. But in reality, neither statement was completely true. The technology simply became... normal. ## Hype Is Loud. Adoption Is Quiet. Social media optimises for novelty. Engineering optimises for reliability. Those are very different incentives. A developer doesn't wake up every morning looking for the newest framework. They want tools that solve problems. That means once a technology becomes stable enough to integrate into production, it often becomes less interesting to talk about. Ironically, that's when it becomes most valuable. Nobody writes viral posts saying, > "Our authentication service worked flawlessly for the 900th consecutive day." Nobody gets thousands of likes for saying, > "We've been using PostgreSQL successfully for five years." The same thing happens with AI. Once a technology starts quietly delivering value inside real products, it stops generating headlines. The conversation moves elsewhere. The work continues. ## The Influencers Move On. The Builders Don't. The people chasing attention have to keep moving. Their audience expects something new every week. But builders don't have that luxury. Builders still have bugs to fix, customers to support, systems to scale, security reviews to pass, budgets to justify, production incidents to investigate. They don't replace a working solution every month simply because a newer one is trending on X. Instead, they keep improving what already works. That's why the technologies that quietly survive the hype cycle often become the foundation of tomorrow's software. ## Maybe We're Measuring the Wrong Thing We often judge the importance of a technology by how much people are talking about it. But popularity is a poor proxy for usefulness. If anything, the opposite is often true. When everyone is talking about a technology, expectations are usually at their highest. When almost nobody is talking about it anymore, engineers have finally had enough time to understand its strengths, limitations, and practical use cases. That's when adoption begins. Not with viral posts, but with production deployments. ## The Real Lifecycle of AI Innovation Looking back, OpenClaw wasn't the story. It was simply the latest example. Every major AI breakthrough seems to go through the same journey: * Discovery * Hype * Unrealistic expectations * Disappointment * Quiet adoption * Integration into everyday software By the time the internet has moved on to the next breakthrough, thousands of developers are still building with the previous one. Most users never notice. And that's exactly the point. The best technologies eventually become invisible. Nobody opens a browser and thinks about the JavaScript engine. Nobody sends an HTTPS request and celebrates TLS. Nobody asks whether their IDE uses incremental compilation. Those technologies became infrastructure. I suspect the same thing will happen with many of today's AI innovations. Five years from now, users won't care whether a feature uses an AI agent, MCP, RAG, or something that hasn't even been invented yet. They'll simply expect the software to work. And perhaps that's the ultimate success of any technology. **The best AI technologies don't trend forever. They disappear into the software we use every day.** * * * ======================================== --- # Stop Using Your Smartest AI Model for Everything: A Practical Workflow That Saves Time and Tokens - URL: https://akshaykgupta.me/blog/stop-using-your-smartest-ai-model-for-everything/ - Author: Akshay K Gupta - Published: Jun 28, 2026 - Tags: software-engineering, artificial-intelligence, software-development, ai-model-comparisons - Description: Most developers default to the strongest AI model for every task. Here’s why treating AI models like a specialised engineering team leads to faster iterations, lower token costs, and better software development. import Figure from '../../../components/mdx/Figure.astro'; import workflowImg from './4step-workflow.png'; ## **The Mistake I Didn’t Realise I Was Making** For a long time, I thought I was being efficient. Whenever I opened my GitHub Copilot, I instinctively selected the most capable model available. It didn’t matter whether I was designing a distributed system, writing a React component, fixing a CSS issue, or generating a Git commit message — the same model handled everything. After all, if it’s the smartest model, shouldn’t it produce the best results? **Technically**, yes. **Practically**, not always. Over time, I noticed three recurring problems: * Responses were often far more detailed than the task required. * Simple requests took longer than necessary. * Token consumption quietly kept increasing. None of these issues was significant on its own. But together, they created friction throughout my daily workflow. The turning point came when I stopped thinking about AI models as different versions of the same assistant. Instead, I started treating them like members of an engineering team. ## **Your AI Models Are Not One Employee — They’re an Entire Team** Imagine running a software company. Would you ask your Principal Architect to rename variables? Would your Staff Engineer spend the afternoon formatting documentation? Would your Engineering Director write every unit test? Probably not. Good engineering teams succeed because everyone has a role that matches their strengths. I realised AI models work surprisingly well under the same philosophy. Instead of asking one model to do everything, I assign work based on the complexity of the task. That simple shift changed how I work every day. ## **My Four-Step Workflow**
### **1\. Think in Sonnet** This is where I do the heavy thinking. When I’m trying to understand a problem, compare design options, plan an architecture, decompose a feature, or evaluate trade-offs, I want a model that reasons well and communicates clearly. Typical tasks include: * System design * Architecture discussions * Feature planning * Breaking down complex requirements * Technical brainstorming * Reviewing implementation approaches At this stage, I’m not writing code. I’m deciding _what_ should be built. ### **2\. Build in Codex** Once the direction is clear, I switch to implementation. This is where speed matters. Instead of asking a reasoning-focused model to generate production code, I move to a model optimised for coding tasks. Typical work includes: * React components * Backend APIs * Python utilities * Refactoring * Database access layers * Unit tests * Automation scripts By separating thinking from implementation, I spend less time rewriting generated code and more time shipping features. ### **3\. Polish in Mini** Not every task deserves deep reasoning. In fact, a surprising amount of software development consists of lightweight work. Examples include: * Tailwind adjustments * Documentation edits * Git commit messages * Pull request summaries * Renaming variables * Updating comments * Small bug fixes * Writing release notes Using a lightweight model for these tasks makes the interaction feel almost instantaneous while keeping token usage significantly lower. Individually, these tasks are tiny. Collectively, they happen dozens of times every week. That’s where the savings become noticeable. ### **4\. Escalate to Opus** Every engineering team has specialists. You don’t involve them in every decision. You call them when the problem becomes genuinely difficult. That’s how I think about larger reasoning models. I reserve them for situations like: * Complex debugging * Performance bottlenecks * Difficult architectural trade-offs * Multi-system analysis * Ambiguous production issues * Challenging refactoring decisions These models are incredibly powerful. But power isn’t the same thing as efficiency. Using them to generate a simple component is a bit like hiring a Formula One driver to commute through city traffic. You’ll reach the destination. Just not in the most practical way. ## **The Biggest Lesson** The mistake isn’t using powerful models. The mistake is assuming every task deserves one. As engineers, we’re already familiar with choosing the right tool for the job. We don’t use Kubernetes for a personal todo app. We don’t spin up distributed infrastructure for a weekend prototype. We constantly make trade-offs. AI model selection should follow exactly the same principle. ## **The Results I’ve Seen** After adopting this workflow, a few things changed. First, my token consumption dropped without consciously trying to optimise it. Second, development became faster because I wasn’t waiting for overly detailed responses to simple requests. Third, I spent less time trimming generated code that solved problems I never asked about. Perhaps the biggest improvement wasn’t measurable at all. I became more intentional. Before sending a prompt, I naturally started asking myself: _“What kind of task is this?”_ That single question usually tells me which model should handle it. ## **Will This Workflow Work for Everyone?** Probably not. Different developers have different habits. Some spend most of their day designing systems. Others primarily write code. Some use AI for documentation. Others rely on it for debugging. The exact model lineup will also continue changing as new models appear. That’s why I don’t think this framework is about Sonnet, Codex, Mini, or Opus specifically. It’s about assigning work based on capability instead of habit. The names may change. The principal probably won’t. ## **Final Thoughts** One of the biggest productivity gains in software engineering rarely comes from working harder. It comes from reducing unnecessary friction. For me, that meant treating AI models less like a single assistant and more like a well-balanced engineering team. Think with one. Build with another. Polish with a third. Escalate only when the problem truly demands it. It’s a simple mindset shift, but it’s made my workflow faster, cheaper, and far more deliberate. ======================================== --- # HTTP QUERY: Why Enterprise Adoption Will Take Years - URL: https://akshaykgupta.me/blog/http-query-method-why-it-matters/ - Author: Akshay K Gupta - Published: Jun 24, 2026 - Tags: http-query, software-development, enterprise-architecture, rest-api, web-standards - Description: Why It Matters and Why Enterprise Adoption Will Take Years. The HTTP QUERY method solves one of REST’s oldest design problems. The HTTP QUERY method solves one of REST’s oldest design problems. But before it becomes mainstream, enterprise servers, API gateways, client libraries, and tooling ecosystems all need to catch up. For decades, REST API designers have lived with an uncomfortable compromise. Need to retrieve data? Use GET. Need to send a complex search object containing filters, sorting, pagination, nested conditions, or hundreds of IDs? Well… GET wasn’t really designed for that. So we started using POST. Not because POST was the correct semantic choice. But because it was the only practical one. Now, that may finally be changing. The newly standardised **HTTP QUERY** method introduces something many architects have wanted for years: * A **safe** request like GET (it doesn’t modify server state) * Support for a **request body** * Clear semantics that distinguish querying from creating or updating resources On paper, it’s exactly what modern APIs have been missing. But before you rush to redesign your APIs, there’s a reality check. HTTP QUERY is technically elegant. Enterprise adoption, however, is a completely different challenge. ## **The Problem HTTP QUERY Solves** Consider a product search API. With **GET**, you quickly end up with URLs like: ```plaintext GET /products?category=smartphone&brand=Apple&brand=Samsung&priceMin=50000&priceMax=70000 ``` Now imagine adding: * nested filters * logical AND/OR conditions * faceted search * geo filters * date ranges * personalization rules The URL becomes unreadable. The obvious alternative is **POST**: ```plaintext POST /products/search ``` ```json { "category": "smartphone", "brands": ["Apple", "Samsung"], "price": { "min": 50000, "max": 100000 } } ``` Every architect has built APIs like this. The problem? POST implies that something is being processed or created. But this endpoint is simply reading data. The semantics have always been slightly wrong. HTTP QUERY fixes exactly this problem. It gives us a request body while still clearly communicating that ***this operation is read-only.*** That’s a huge improvement for API design. ## **So, Why Aren’t We Using It Already?** Because protocols evolve much faster than enterprise ecosystems. Supporting a new HTTP method isn’t just about changing application code. Every component between the client and your application needs to understand or at least tolerate that method. And that’s where reality gets complicated. ## **The Four Layers That Must Support HTTP QUERY** Many discussions stop at the application layer. In reality, enterprise architectures have four independent areas that must evolve. ### **1\. Application Servers and Frameworks** Your REST framework needs to recognise QUERY. Whether you’re using Spring Boot, [ASP.NET](http://ASP.NET) Core, Express, FastAPI, or another framework, support has to exist before your controller can even receive the request. Otherwise, you’ll likely see: * 405 Method Not Allowed * 501 Not Implemented The API never executes. ### **2\. API Gateways, Proxies, and Network Infrastructure** This is where things become significantly harder. An enterprise request typically flows through multiple infrastructure components before reaching your application. ```plaintext Client │ HTTP Client Library │ Corporate Proxy │ CDN / WAF │ API Gateway │ Load Balancer │ Application Server │ REST Framework ``` Every one of these components needs to correctly forward QUERY requests. If even one product rejects unknown HTTP methods, the request never reaches your service. Large organisations often have dozens of these layers spread across different vendors and cloud providers. And updating them isn’t a weekend project. ### **3\. Client Libraries and SDKs** Your application server may support QUERY. Your gateway may support QUERY. But can your **client** actually send it? Different languages have different HTTP libraries. Generated SDKs, mobile networking stacks, Browser APIs, Enterprise integration platforms, API testing tools, etc., have built-in assumptions around the traditional HTTP verbs. Until the client ecosystem matures, developers will continue defaulting to GET and POST. ### **4\. The Enterprise Tooling Ecosystem** This is the most underestimated challenge. Modern APIs are surrounded by an enormous ecosystem of tooling: * OpenAPI specifications * Swagger UI * SDK generators * API documentation portals * Security scanners * Web Application Firewalls * API governance tools * Monitoring platforms * Observability systems * Analytics pipelines Every one of these tools has spent years optimising around the classic HTTP methods. Supporting QUERY isn’t just adding another keyword. It requires updates across thousands of products and open-source projects. ## **The Biggest Challenge Isn’t Technology** It’s Standardisation. Large enterprises rarely upgrade every system simultaneously. One business unit may be running the latest API Gateway. Another may still be using infrastructure deployed six years ago. One client application may support QUERY. Another generated SDK may not. One cloud provider may support it today. Another may add support next year. Enterprise architectures move deliberately because stability matters more than novelty. That’s why adoption of HTTP QUERY will likely be measured in years rather than months. We’ve Seen This Story Before. The web has evolved through gradual adoption many times. HTTP/2, HTTP/3, TLS 1.3, etc, solved real technical problems. But each required years before becoming commonplace. HTTP QUERY will likely follow the same path. Not because it lacks value. But because distributed systems are built on layers of software that all need to evolve together. ## **Why This Is Still an Excellent Step Forward** Despite the slow adoption curve, **HTTP** **QUERY** represents an important milestone in API design. For the first time, HTTP offers a standardised way to express a read-only operation that also carries a structured request body. As APIs continue to power AI agents, search platforms, analytics systems, enterprise integrations, and increasingly complex query workloads, having more precise HTTP semantics becomes increasingly valuable. Cleaner protocols lead to clearer APIs. Clearer APIs lead to better tooling. Better tooling leads to better developer experience. The web has always evolved through incremental improvements that compound over time. HTTP QUERY feels like one of those improvements. You probably won’t be deploying it across your enterprise architecture next quarter. But ten years from now, new developers may look at `POST /search` the same way we look at SOAP today—a practical workaround from an earlier era. Sometimes the most important innovations aren’t the ones that change everything overnight. They’re the ones that quietly make the next decade of software a little more elegant. * * * ======================================== --- # Who’s Allowed to Build Your Bank’s Software that manages Billions of Dollars? Anyone. - URL: https://akshaykgupta.me/blog/who-is-allowed-to-build-your-software/ - Author: Akshay K Gupta - Published: Jun 19, 2026 - Tags: enterprise-architecture, compliance, software-engineering - Description: Banks, hospitals, and airlines run on code written by people with no license to write it. Here's why that's not a flaw — it's the system. Doctors, lawyers, and accountants all need a license to practice. But the people writing the code running your bank, your hospital, and your AI assistant need none — here’s the surprisingly good reason why. Doctors have medical councils. Touch a patient without a degree? It’s a crime. Lawyers have bar councils. Argue in court without clearing the exam? Illegal. Chartered Accountants have the ICAI. Sign an audit report without qualifying? Impossible. Now ask yourself: what’s stopping the person writing the code behind your bank’s payment system, your hospital’s patient records, or the AI agent quietly reading your inbox? Nothing. No degree required. No license to revoke. No central board to certify you’re fit to practice. And here’s the part that should unsettle you more: the industry is *proud* of it. ## **We Don’t Care About Your Degree** Software engineering is probably the only high-stakes profession on Earth where its own leaders boast about having no gate at all. Crack the technical interview, prove you can solve the problem, and you get the keys to the castle — no questions asked about where, or whether, you studied. A self-taught programmer with a laptop and a Claude Code subscription can be handed the responsibility of writing code for systems that move billions of dollars or keep hospitals running. There’s no professional body standing between them and production. > *Software is the only high-stakes industry where its leaders proudly say: “We don’t care about your degree.”* It sounds like a terrifying paradox — critical infrastructure, run by anyone who can pass a whiteboard test. But look closer, and there’s a very deliberate logic for why a single, central gatekeeper has never existed in tech — and probably never will. ## **1\. The Industry Is Too Broad for One Stamp of Approval** A front-end engineer building a checkout flow, an embedded engineer writing firmware for a pacemaker, a cloud architect designing core banking infrastructure, and an AI engineer orchestrating autonomous agents are not in the same profession by any meaningful definition. They share a job title and almost nothing else. A single universal license covering all of that would have to be so generic it would mean nothing — the equivalent of certifying every doctor on Earth, from dermatologists to neurosurgeons, with one shared exam. ## **2\. Tech Regulates the Work, Not the Worker** This is the real twist: software *is* regulated — just not the way medicine or law is. Instead of licensing the individual, the industry attaches accountability directly to the system being built. * Writing avionics software? **DO-178C** has to sign off, not you. * Handling patient data? **HIPAA** and a stack of compliance controls govern what your code can and can’t do. * Processing a credit card transaction? **PCI-DSS** and banking regulators are the real gatekeepers. > *Tech doesn’t license the worker. It regulates the work.* The accountability sits with the outcome, not the diploma on the wall. Nobody asks for your certificate before a payment goes through — they ask whether the system passed its compliance audit. ## **3\. The Field Moves Faster Than Any Certificate Can Track** Even if a universal license existed, it would expire the moment it was printed. Technology doesn’t evolve in decades, the way the foundations of medicine or contract law do. It evolves in product cycles. > *A certification earned ten years ago says almost nothing about whether you can design a secure distributed system, build a reliable AI workflow, or architect a resilient cloud platform today.* A board exam written in 2016 has no opinion on Kubernetes, LLM agents, or zero-trust architecture, because none of it existed yet. Trying to centrally certify software engineers would be like trying to license meteorologists for a climate that changes every eighteen months. ## **So What Actually Keeps the Lights On?** Not a license. Not a diploma. Something more distributed, and arguably more rigorous: Architecture reviews. Automated testing. Peer review. Observability. Compliance audits. Continuous validation, every single day, on every system, indefinitely. It’s not a single gate you pass through once at age twenty-five. It’s a thousand smaller gates you pass through every week, for your entire career. > *Software safety doesn’t come from a license. It comes from the relentless, boring discipline of checking the work — every day, forever.* That’s the part that doesn’t fit on a framed certificate. But it’s also, quietly, why a system with no bar exam still manages to run the world. So no, there’s no bar exam for software engineers. There probably never will be one. The test isn’t given once, in a room, by a board — it’s running right now, in production, on every system you’ve ever touched, and it never stops grading. The real credential in software isn’t a piece of paper. It’s the system still standing the morning after. No board can issue that one. You earn it again, every single day, whether anyone’s watching or not. So the next time someone asks who’s qualified to build the systems the world runs on — maybe the better question is: *qualified by whose test?* * * * ======================================== --- # Is Git Becoming a Legacy Skill in the Age of AI? - URL: https://akshaykgupta.me/blog/is-git-becoming-a-legacy-skill/ - Author: Akshay K Gupta - Published: Jun 14, 2026 - Tags: git, artificial-intelligence, software-engineering, productivity - Description: A recent incident made me rethink one of software engineering’s most fundamental skills. For years, mastering Git was considered part of the software engineering toolkit. Every developer eventually had to learn the difference between rebasing and merging, navigate painful merge conflicts, and recover from the occasional mistake that inevitably found its way into the commit history. Knowing Git wasn’t optional. It was expected. You didn’t have to memorise every command, but when things went wrong, someone on the team needed to know how to untangle the mess. Lately, however, I have started to wonder whether that expectation is changing. Not because version control is becoming less important. But because AI is increasingly handling the operational complexity on our behalf. ### **The Git Badge of Honor** For more than a decade, proficiency with Git represented a certain level of engineering maturity. There was almost a cultural aspect to it. Developers swapped stories about impossible merge conflicts, disastrous force pushes, and heroic recoveries involving obscure Git commands that few people understood but everyone respected. Knowing how to manipulate commit history wasn’t just useful, it was often viewed as a mark of competence. And to be fair, Git isn’t exactly known for its friendly user experience. The difference between `merge`, `rebase`, `reset`, `revert`, and `cherry-pick` can feel obvious only after years of experience. Until then, every command comes with a healthy dose of anxiety. ### **The Mistake Every Developer Dreads** A few weeks ago, I made one of those mistakes. I was moving quickly and accidentally staged and pushed a configuration file containing sensitive credentials and keys to a remote repository. The moment I realised what had happened, I had the same reaction many developers have had before me: *Oh no.* Historically, this kind of incident triggered a very specific sequence of events: * Stop everything. * Search documentation and Stack Overflow. * Figure out the correct history-rewriting approach. * Hope you remember the exact git command syntax * Rewrite history carefully. * Force push the cleaned repository. * Coordinate with teammates to avoid pulling the compromised history. * Double-check that nothing else was accidentally broken. It wasn’t impossible. But it was stressful. And it often required knowledge that most engineers don’t use frequently enough to retain confidently. ### **This Time Was Different** This time, instead of opening half a dozen browser tabs and piecing together commands from old blog posts, I turned to GitHub Copilot. I described the situation. Copilot understood the context of the problem, suggested the appropriate recovery strategy, performed the necessary Git operations, verified that the sensitive file had been removed from the repository history, and walked me through the final validation steps before pushing the cleaned repository state. What had traditionally been an hour-long interruption became a process measured in minutes. The difference wasn’t just speed. It was cognitive load. I didn’t have to recall rarely used commands or translate documentation into action. I stayed focused on the outcome while the AI handled much of the operational detail. ### **Are We Witnessing a Shift?** This experience left me thinking about a broader trend. Throughout the history of software engineering, we’ve continuously moved up the abstraction ladder. There was a time when writing assembly language was a common requirement. Then higher-level programming languages emerged. Infrastructure management evolved into Infrastructure as Code. Container orchestration simplified deployment concerns that once demanded extensive operational expertise. Each transition followed a familiar pattern: The underlying concepts remained important, but the mechanics became increasingly automated. Perhaps Git is entering that phase as well. ### **What Still Matters** To be clear, I don’t believe version control knowledge is becoming irrelevant. Understanding concepts such as: * Branching strategies * Isolation of work * Code review workflows * Collaboration models * Release management * Deployment pipelines remains incredibly valuable. These concepts shape how teams build software effectively. What may be changing is the expectation that every engineer must memorise the exact syntax required to recover from every possible Git disaster. ### **From Memorisation to Intent** Maybe the real shift isn’t about Git at all. Maybe it’s about how expertise itself is evolving. Historically, expertise often meant retaining detailed procedural knowledge. Today, expertise increasingly involves understanding intent, evaluating trade-offs, and validating outcomes while delegating implementation details to intelligent tools. In other words: Knowing *what* should happen may become more important than remembering *exactly how* to make it happen. ### **The Future of Git Skills** Will developers still need to understand Git? Absolutely. Will they need to memorise obscure commands that they use once every few years? Perhaps not. In the same way, calculators didn’t eliminate mathematics and cloud platforms didn’t eliminate architecture, AI assistants may not eliminate Git expertise. But they might redefine it. The future software engineer may spend less time wrestling with command syntax and more time focusing on design, systems thinking, and business outcomes. And maybe that’s progress…!!! * * * ======================================== --- # Stop Putting UI Inside Your MCP Server: The Abstract UI Schema Pattern - URL: https://akshaykgupta.me/blog/mcp-server-the-abstract-ui-schema-pattern/ - Author: Akshay K Gupta - Published: Jun 5, 2026 - Tags: mcp, mcp-server-pattern, system-architecture, enterprise-architecture, architecture-pattern, cyber-security - Description: An enterprise architecture pattern for rendering analytics across Copilot, Teams, Claude Desktop, and custom applications without creating client-specific backend code import Callout from '../../../components/mdx/Callout.astro'; import Mermaid from '../../../components/mdx/Mermaid.astro'; The moment your MCP server starts generating Adaptive Cards, React Components, or HTML fragments, you’ve already coupled your architecture to a client. Over the past year, while I was studying, reviewing and building MCP Servers for analytics, reporting, operational intelligence, and business process automation, one architectural problem kept on appearing over and over again. The MCP Server would successfully fetch data from enterprise systems. The LLM would successfully invoke the tool. The business logic would work perfectly. And, then everything would fall apart at the presentation layer. A business user would ask: > *"Show me the sales trend for the last four quarters."* The server would return structured data. But then a new question emerged: **How should the data be displayed:** * MS Teams and Copilot wanted Adaptive Cards. * Claude Desktop preferred Markdown. * Custom React application wanted charting libraries. * And, future clients would undoubtedly want something else. The natural temptation is to make the MCP Server generate the UI. And, that is exactly where the architectural problems begin. ## **The Hidden Anti-Pattern in Many MCP Implementations** Many teams start with an architecture that looks something like this: B A --> C A --> D A --> E `} /> Initially, this feels efficient until a second client arrives. Now the server suddenly needs: * Adaptive Cards * HTML * React Components * Markdown * Mobile Layouts * Future visualisation frameworks. The backend becomes responsible for front-end rendering decisions. Every new client creates additional complexity. Every UI redesign requires backend changes. Every platform-specific feature leaks into the MCP layer. What started as an integration server slowly transforms into a presentation engine. That is architectural coupling. ## **The Architectural Principles Behind This Pattern** While designing enterprise MCP ecosystems, I found that several well-established software architecture principles can be applied directly to MCP implementations. The result is what I call the `Abstract UI Schema Pattern.` This pattern is not an attempt to reinvent architecture. Rather, it extends proven software design philosophies into the rapidly evolving MCP ecosystem. ### **1\. Separation of Concerns (SoC)** One of the most fundamental principles in software architecture is the Separation of Concerns. In traditional applications: * Business Logic belongs in the backend. * Presentation Logic belongs in the frontend. However, many MCP implementations unintentionally blur this boundary by embedding client-specific presentation details directly into tool responses. The Abstract UI Schema Pattern restores this separation by ensuring: * MCP Servers own data, meaning, and business logic. * Client Applications own rendering, layout, and user experience. ### **2\. Adapter Pattern** The client-side translation layer is effectively an implementation of the classic Adapter Pattern. A single abstract MCP response can be translated into multiple platform-specific representations: * Adaptive Cards * React Components * Markdown Tables * Future UI Frameworks without requiring changes to the MCP Server itself. ### **3\. APIs Return Data, Not User Interfaces** Modern REST APIs, GraphQL APIs, and Microservice Architectures generally return data rather than rendered user interfaces. A backend service returns: ```json { "revenue": 1200000 } ``` rather than: ```html
...
``` The **Abstract UI Schema Pattern** extends this philosophy into MCP ecosystems. Instead of returning Adaptive Cards, HTML Fragments, React Configuration, or platform-specific visualisation definitions, the MCP Server returns semantic information that clients can interpret and render independently. In many ways, the Abstract UI Schema Pattern can be viewed as applying decades of API and frontend architecture best practices to the emerging world of MCP-based AI integrations. # **The Abstract UI Schema Pattern Architecture** The principle is simple: > *The MCP Server defines meaning. The MCP Client defines presentation.* Instead of returning platform-specific UI markup, the MCP Server returns an abstract visualisation contract. The payload describes: * What should be rendered * What data exists * How the data behaves logically But, it never specifies: * Adaptive Cards * React Components * HTML * CSS B B --> C C --> D C --> E C --> F C --> G `} /> **What the MCP Server Returns** Instead of this: ```json { "type": "AdaptiveCard", ... } ``` the MCP Server returns: ```json { "status": "success", "textSummary": "Q3 revenue increased significantly.", "renderType": "chart", "meta": { "type": "bar", "title": "Revenue by Quarter", "xAxisKey": "quarter", "yAxisKey": "revenue" }, "payload": [ { "quarter": "Q1", "revenue": 450000 }, { "quarter": "Q2", "revenue": 600000 } ] } ``` There is no mention of : * Teams * Copilot * React * HTML * CSS The payload is purely semantic. ## **The Translation Layer** Every client receives the exact same MCP response. Each client decides how to render it. B B --> C C --> D C --> E C --> F `} /> The MCP contract remains unchanged. Only translators evolve. ## **The Ownership Boundary** Before diving further, it’s important to understand the architectural boundary this pattern establishes. Rendering `} /> This is the most important concept in the entire pattern. ### **Example 1: MS Teams** The Team adapter converts the abstract schema into Adaptive Card components. The MCP Server never knows Adaptive Card exist. That’s a MSTeams concern, not a Server Concern. ### **Example 2: Custom React Apps** The same payload can drive: * Rechart * Chart.js * Highcharts * D3.js No server changes required. No new MCP tools required. No contract modifications required. ### **Example 3: Claude Desktop** Claude Desktop cannot render React charts. Instead, the translation layer degrades gracefully. The same payload can be transformed into: ```plaintext | Quarter | Revenue | |----------|----------| | Q1 | 450000 | | Q2 | 600000 | ``` The same payload still works. The experience changes. The contract does not. ## **Why This Pattern Scales Better** ### **1\. Reduced Token Consumption** UI definitions are surprisingly expensive. Embedding Adaptive Card structures, HTML blocks, or visualisation instructions inside MCP responses increases payload size significantly. The abstract contract contains only semantic information. As a result, it can significantly reduce token consumption by eliminating presentation-specific markup. The exact reduction varies depending on the complexity of the rendered artefacts and the client ecosystem being supported. ### **2\. Independent Release Cycles** B["Front-end Deployment"] end subgraph Without_Pattern["Without This Pattern"] direction TB C["Front-end Change"] --> D["Backend Change"] D --> E["MCP Change"] E --> F["Deployment"] end `} /> With this pattern, the MCP Contract remains untouched. Frontend teams and backend teams can evolve independently. ### **3\. Future Client Compatibility** Every enterprise eventually adds new AI clients. Today’s stack might include: * Copilot * Teams * Claude Desktop Tomorrow it could include: * ChatGPT Enterprise * Internal AI Portals * Mobile AI Assistants * AR Interfaces B A --> C A --> D A --> E A --> F `} /> ## **Design Rules** We should follow these three rules: ### **Rule #1** For multi-client enterprise ecosystems, I recommend that MCP Servers avoid emitting client-specific UI artefacts. While there are valid scenarios where a single-client MCP deployment may directly emit platform-specific payloads, enterprise environments typically evolve into multi-client ecosystems. The moment a second or third client arrives, backend ownership of presentation logic begins to create unnecessary coupling and maintenance overhead. ### **Rule #2** Most business analytics visualisations can be represented as abstract metadata. There are exceptions. Highly specialised visualisations such as: * GIS maps * CAD viewers * 3D models * Domain-specific rendering engines may require richer presentation contracts. However, the vast majority of business reporting, KPI dashboards, trend analysis, and operational analytics can be represented using abstract metadata structures. ### **Rule #3** Every client should own its rendering strategy. Rendering belongs to the edge. Not the core. * * *
When Not to Use This Pattern

This pattern is ideal for:

  • Analytics

  • KPI Dashboards

  • Business Intelligence

  • Operational Monitoring

  • Executive Reporting

It may be excessive for:

  • Simple CRUD Tools

  • Basic Text Responses

  • Single-Client MCP Deployments

If you only have one client and never expect another, direct rendering may be perfectly acceptable.

But most enterprise ecosystems don’t stay that simple for long.

* * * ## **Final Thoughts** One lesson I’ve learned is that client diversity grows much faster than backend complexity. The first client is easy. The fifth client exposes every architectural shortcut. The Abstract UI Schema Pattern addresses that challenge by applying established software architecture principles — Separation of Concerns, Adapter Patterns, API-first design — to the world of MCP. The MCP Server becomes a source of meaning. The client becomes a renderer of meaning. And that separation turns out to be one of the most important architectural boundaries in scalable MCP systems. Because the moment your MCP server starts generating UI, it stops being a protocol server and starts becoming a frontend framework. * * * ======================================== --- # How to Build a Secure MCP Server: The Middle-Tier Gatekeeper Pattern - URL: https://akshaykgupta.me/blog/mcp-the-middle-tier-gatekeeper-pattern/ - Author: Akshay K Gupta - Published: May 20, 2026 - Tags: mcp, mcp-server-pattern, system-architecture, enterprise-architecture, architecture-pattern, cyber-security - Description: Secure your enterprise data warehouse from prompt injections when connecting LLMs via the Model Context Protocol. import Figure from '../../../components/mdx/Figure.astro'; import Mermaid from '../../../components/mdx/Mermaid.astro'; import middleTierImg from './middle-tier-enforcement.png'; Imagine this scenario: You’ve just deployed a brilliant enterprise AI assistant using the **Model Context Protocol (MCP)**. It connects your Enterprise Copilot directly to your enterprise data warehouse (e.g. Snowflake) via a remote SSE/HTTP server. Your executive team is thrilled -they can now ask natural language questions and instantly see revenue breakdowns, instead of waiting for the BI team to generate those Power BI reports. Then, an employee asks the assistant: > "Show me the previous payroll details and filter for the CxO's salary." If your underlying data warehouse relies on a shared service account or lacks fine-grained, row-level access controls mapped to every single end-user (which is the case for most enterprises), your AI will happily fetch that data. You are exactly one prompt injection away from a massive corporate security incident. How do we fix this when we cannot completely rewrite our database permissions overnight? The answer lies in a decoupled architecture pattern: **the Middle-Tier Policy Enforcement Pattern,** often referred to as the **Application-Level Gatekeeper.** Let’s walk through the problem and build a secure gateway step-by-step. ## **The Problem: The “All-Powerful” AI Agent** In an ideal zero-trust architecture, the database handles its own Row-Level Security (RLS) and data governance. In the real world, analytical data warehouses or legacy systems often use a single, unified connection string for applications. If you expose a generic tool like `run_sql_query(query)` to an LLM, the model can be manipulated by malicious user inputs to bypass your structural intent, alter the SQL syntax, or query highly sensitive tables it should never see. > ***The Architectural Pivot:*** *When underlying data systems cannot enforce granular data ownership rules, we must shift the Policy Decision Point (PDP) away from the database and place it squarely inside our remote MCP server. The MCP server stops being a passive translator and becomes a strict, policy-enforcing security gatekeeper.* ## **Building the Gatekeeper Pattern** Implementing this pattern means decoupling *authentication* (who the user is) from *authorisation* (what data they are allowed to see). Here is how you build this flow inside your remote HTTP/SSE MCP server.
### Step 1: Lock the Front Door (No Raw SQL Tools) Never give the LLM the ability to write raw database queries. Instead, abstract your data warehouse tables into rigid, typed, functional tools. * ❌ Vulnerable: `execute_query(sql="SELECT * FROM sales")` * ✅ Secure: `get_regional_sales(region="US")` By forcing the LLM to provide strict, predefined parameters rather than raw code, your MCP server retains total control over the query structure. The LLM changes from a code generator to a parameter supplier. ### **Step 2: Extract the Identity (Token Verification)** When the AI client communicates with your remote HTTP/SSE MCP server, it must forward the user’s authenticated OAuth 2.1 JWT Access Token in the headers. Your MCP server intercepts this bearer token and validates its cryptographic signature against your central Identity Provider (like Okta, Auth0, or Keycloak). Because this is a decoupled architecture, the server safely extracts user identity claims (like user ID or email) entirely from the validated token without constantly querying the database for authentication. ### **Step 3: Enforce Attribute-Based Access Control (ABAC)** Before hitting DWH, your MCP server runs an internal authorisation check using an Attribute-Based Access Control (ABAC) strategy. It matches the user claims extracted from the token against the resource parameters requested by the tool. + JWT Token"] B["Extract Identity Claims
user_email:
alice@company.com"] C["Evaluate ABAC Policies
Does 'alice' have access to
region = 'US'?"] D["Execute Parameterized
Snowflake Query"] E["Raise Strict
Permission Error"] A --> B B --> C C -- Allowed --> D C -- Denied --> E `} /> Your server can evaluate this internally or pass the attributes to a lightweight external policy engine like Open Policy Agent (OPA): * *System Check:* “Does [`user_alice@company.com`](mailto:user_alice@company.com) possess the attribute required to view data in the `US` region?" * If the policy evaluates to true, the request proceeds. If false, the server raises a strict `PermissionError` and halts execution immediately. ### Step 4: Parameterised Execution (No SQL Injection) If authorised, your code programmatically inserts the validated parameters into a hardcoded SQL template using bind variables (%s or ?). ```javascript # A secure, parameterized implementation snippet cursor.execute( "SELECT total_revenue FROM sales_summary WHERE region = %s", (validated_region_parameter,) ) ``` This completely eliminates standard SQL injection vectors, ensuring that whatever data the LLM attempts to pass as a parameter is treated strictly as a string literal, never as executable SQL commands. ## **Mandatory Enterprise Guardrails: Robust Middle-Tier Auditing** Because DWH (Snowflake) only sees queries originating from your central MCP server’s service account, downstream database logs suffer from “identity loss.” Your database logs will show the exact same user account for every query. Therefore, your MCP server must maintain its own tamper-proof, structured audit logs. Every tool invocation must explicitly map the user’s identity to the exact parameter payloads and generated queries to comply with enterprise tracking standards. ## **The Reality Check: Trade-offs & Limitations** While highly effective for systems lacking native row-level security, architects must plan around these real-world constraints: * **Maintenance Overhead:** Your engineering team now owns and maintains a custom permission mapping layer inside the MCP server codebase. If business data structures or organisational roles change, your gateway logic must evolve with them. * **Performance Milliseconds:** Performing cryptographic token validation, policy lookups, and parameter sanitisation on every single tool execution adds minimal latency to the user interaction loop. * **Data Synchronisation Lags:** If user permissions change in your primary HR or Identity directory, there may be a minor propagation delay before your mid-tier gatekeeper recognises the updated authorisation boundaries. Securing AI agents requires moving past the assumption that our databases are perfectly tailored for direct LLM exposure. By treating your remote MCP server as a hardened, policy-enforcing gateway, you can confidently unlock data warehouses like Snowflake for your AI applications without waiting for a multi-month database infrastructure overhaul. * * *