Skip to content

2026

Enforce Tenant Isolation with require_tenant=True

A require_tenant mcp server turns tenant isolation from a check you remember to add into an invariant the framework enforces at build time. Instead of adding a tenant guard to each tool by hand — and hoping the next tool, the next router, and the mounted third-party server all get one too — you set a single flag on the constructor, and every tool the server exposes is forced to authenticate and carry a tenant guard before you write a line of handler code. This post is about the exact mechanics of that flag: what MCPServer(require_tenant=True) does at build time, how to prove it with a runnable unit test, why it covers registration paths you didn't write yourself, and where it is honestly stronger than the opt-in checks other frameworks hand you.

How do you revoke an AI agent's access instantly?

To revoke an AI agent's access the moment it misbehaves, you need a single place to flip — not a scavenger hunt for a leaked string across every service that trusts it. That is exactly what a static per-agent API key can't give you: revoking it means minting a new one, editing every deployment that holds the old value, and redeploying without a gap — all while you may not even be sure which agent leaked it. Back the agent with an identity from your IdP instead, and revocation collapses into one directory operation: disable the identity, and its short-lived, audience-scoped credentials stop validating everywhere, with no server reconfiguration. This post shows the revoke path, why short-lived tokens keep the blast radius small, and how Promptise zero-fills any credential a running agent still holds in memory.

The Real Risks of Running AI-Generated Code In-Process

The risks of running AI-generated code are easy to underestimate, because the failure mode is invisible right up until the day it isn't: the program runs, prints a plausible answer, and only later do you notice it also read your .env, listed /, and made an outbound request you never authorized. This post is a threat-model walkthrough rather than another isolation-layer reference. We are going to trace exactly what a model-written Python snippet can reach when it executes inside your process — the working directory and everything around it, environment-variable secrets, and the open network — using LangChain's PythonREPLTool as the worked example, and then show why Promptise Foundry treats a hardened container as the default path instead of something you remember to bolt on.

How to Roll Out a Breaking MCP Tool Change Safely

To roll out a breaking MCP tool change safely, you publish the new schema as a new version beside the old one and let each client migrate on its own clock — instead of editing the live tool in place and forcing every connected agent to move the instant you deploy. That second path is the default one, and it is why a one-line schema edit so often turns into an incident. An MCP tool's input_schema is a published contract: agents discovered it, built function calls to match, and will keep sending v1-shaped arguments until they change. Add a required field, rename a property, or tighten a type, and every in-flight caller starts getting rejected before your handler even runs.

Rotate an AI Agent's Secret Without Restarting It

To rotate an AI agent's secret without restart, the running process has to be able to swap the credential it holds in memory while it keeps running — and that is precisely the operation most agent stacks make impossible. The usual pattern is to read OPENAI_API_KEY or a downstream service token from the environment once, at construction time, and hand it to a model client or tool. That value is now frozen inside a live object. When the key leaks, expires, or hits its scheduled rotation, your only lever is to rebuild the client — and for a long-running, self-triggering agent, rebuilding means a restart that tears down the accumulated context, the conversation buffer, and the lifecycle state you worked so hard to keep durable. This post shows how Promptise Foundry's runtime makes the secret a per-process governance concern instead: ${ENV_VAR} resolution at start, TTL expiry, hot rotation with no restart, and zero-fill revocation on stop — with the value never written to the journal, checkpoint, or status output.

Route AI Agent Approvals to Slack with Signed Webhooks

To route AI agent approvals to Slack — or PagerDuty, or an internal review app — the decision has to leave your agent's process entirely and land in front of a human who lives in that channel, not at the terminal that happens to be running the agent. That is a different problem from the usual "pop a confirm dialog in the calling app." The reviewer for a $5,000 refund is on call in an ops channel; they are never going to be watching a Python REPL. This post wires the same server-side approval gate that enforces on every MCP client to an external channel using WebhookApprovalHandler: it POSTs an HMAC-signed request to your own service, polls for the verdict, and denies by default if the clock runs out — a one-line swap for the in-process reviewers, with no change to the tool.

How to Run AI-Generated Code Safely: The 2026 Field Guide

To run AI-generated code safely you have to satisfy two requirements at once, and most stacks only meet one of them: can the model's code escape the box? and is every tool that code reaches inside the box still governed the way the rest of your agent is? Containment answers the first. Almost nothing answers the second. This field guide contrasts the three ways teams actually run model-written code today — an in-process REPL, a bolt-on third-party sandbox, and a hardened first-party sandbox with a governed tool bridge — and shows why Promptise Foundry treats both containment and per-call tool governance as first-class parts of one layer instead of two separate integrations you assemble yourself.

Same user_id, Two Tenants: Why That Isn't Isolation

The problem with the same user_id across two tenants is that it looks fine right up until it doesn't: two of your customers, Acme and Globex, each have a user literally named alice, and the day both are active, whatever you key memory, cache, and conversation history on had better distinguish them. If that key is user_id alone, it doesn't — and the failure is silent. No exception, no log line, just Acme's alice occasionally reading Globex's alice's data. This post is about why a per-user key is not a per-tenant key, what an injective isolation key is, and the subtler risk most treatments skip: not just accidental collision, but deliberate forgery of another tenant's namespace.

Can Your Agent Exfiltrate Data? Sandboxing Code With No Network

To sandbox agent code with no network is the single highest-leverage control you can put between a code-writing agent and a data breach — because a program with an open socket doesn't need a bug to exfiltrate your data, it just needs a plausible-looking line the model was talked into writing. A code interpreter that "does some math" also has your process's network stack, and one urllib.request.urlopen turns a local read into a POST to attacker.example. Cutting the egress is obvious. The reason teams don't is subtler, and it's the honest problem this post is about: for most sandboxes, cutting the network also cuts the program off from the very tools it exists to use. This is how Promptise Foundry breaks that trade-off — NetworkMode.NONE, auto-set for the code-action pattern, where the isolated program's only reach to the outside world is your tools, invoked over a filesystem bridge that needs no network at all.

Securing Agent-Written Code with a Docker Sandbox

Sandboxed code execution for AI is the difference between an agent that drafts a Python script and an agent that runs it on your production host with your credentials in the environment. The moment you let a model write and execute code — for data analysis, glue scripts, or a self-modifying "open mode" agent — the generated script is untrusted input, no matter how good your prompt is. This post is a decision guide to the specific isolation layers that actually matter, and how to turn them on. By the end you will know exactly what a hardened container gives you, which of those layers most "sandbox" wrappers quietly skip, and how to run generated code with no blast radius.

How to Schedule an AI Agent with Cron Triggers

Building a scheduled AI agent usually starts with the same advice you find everywhere: wrap your Python script in system crontab and walk away. That works until you notice the agent has no memory of yesterday's run, no record of what it did, and no ceiling on how much it can spend. This post shows you a better pattern — attach a CronTrigger to a persistent AgentProcess so every scheduled run shares a conversation buffer, a durable journal, and governance limits. By the end you will have a cron AI agent running on a real schedule in about five lines of configuration.

Stop Secrets Leaking into LLM Prompts and Tool Calls

Secret detection for LLM systems is the guardrail almost nobody instruments, and it is the one that quietly turns a helpful agent into an exfiltration channel. Everyone hardens the obvious surfaces — auth on the API, TLS on the wire, secrets in a vault — and then pipes raw user input, model output, and tool arguments straight past all of it. An API key pasted into a support chat, a DATABASE_URL echoed back in a debugging answer, an RSA private key baked into code the sandbox is about to run: each one is a credential leaving your trust boundary in plain text. By the end of this article you will know exactly where those leaks happen and how to layer a local, zero-network CredentialDetector over your agent so keys get caught the moment they appear.

Secure Agent-to-Agent Authentication in Practice

Secure agent-to-agent communication is the part of every multi-agent demo that quietly gets skipped: one agent delegates a task to another, the second agent acts, and when you open the log the only actor recorded is "the assistant." That is not an audit trail — it is a shrug. If a planner agent asks a payments agent to issue a refund, you need to know which agent asked, whether the callee was allowed to trust it, and where that decision landed in a tamper-evident record. By the end of this article you will know how Promptise Foundry propagates a verifiable caller identity through a delegation call and lands the answer to "who delegated to whom" in an HMAC-chained audit log.

How to Secure an MCP Server on the Public Internet

To secure an MCP server on the public internet you have to accept one uncomfortable fact first: the moment your server has a public URL, every tool you registered becomes a callable endpoint for anyone who finds it — not just your agent, but any script, scanner, or rogue MCP client on Earth. A bearer token is table stakes, and it is not hardening. Hardening is what happens after auth: capability checks per tool, limits that survive a burst, breakers that stop a cascade, a trail you can prove wasn't edited, and a human in the loop on the calls that move money. This post wires all of that into one middleware chain you can copy, run offline, and ship.

Reflection, Self-Critique & Self-Consistency Agents

A self-critique agent is an LLM that checks its own work before it answers — it drafts a response, inspects that draft for mistakes, and fixes them in the same step. The appeal is obvious: catch the careless error before the user ever sees it. The catch is that reflection is not free, and most teams bolt it onto models that don't need it. By the end of this article you'll know which introspection techniques pay for themselves, which mostly burn tokens, and how to add a cheap self-check to a small model in a single line.

Build Self-Modifying AI Agents with Open Mode

A self-modifying AI agent — one that can rewrite its own prompt, author a new tool, or connect to another server while it's still running — sounds like exactly the kind of thing you should never ship to production. The instinct is right: an agent with unrestricted write access to its own configuration is a liability. But "never" is the wrong lesson. The right one is never without guardrails. By the end of this post you'll know what Promptise Foundry's open mode actually lets an agent do, the concrete safeguards that box it in, and how to enable it in a .agent manifest so an agent can safely author its own first tool.

Can a Paraphrase Leak Another Tenant's Cached Answer?

A semantic cache cross-tenant leak is the failure mode that only similarity caching can produce: tenant B types a paraphrase of a question tenant A already asked, the two queries embed to nearly the same vector, and — without a caller-scoped partition — the lookup hands tenant B the completion Promptise stored for tenant A. An exact-match cache can never do this. It keys on the literal prompt string, so a reworded question misses and goes to the model. The moment you cache by meaning to save money, you also open a channel where meaning, not identity, decides who sees what. This post isolates that leak vector precisely, and shows how Promptise Foundry confines every similarity search to the caller's own tenant-qualified partition — by default, and fail-closed.

Semantic Caching for LLMs: Cut API Costs 30-50%

A semantic cache for LLMs serves a stored answer when a new question means the same thing as one you already answered — not just when the two strings match byte for byte. That is the difference between a cache that almost never hits (exact-match) and one that quietly absorbs the "how do refunds work?" / "what's your refund policy?" / "can I get my money back?" long tail that real users type. This post skips the tutorial-grade theory and focuses on the two things that decide whether similarity-based caching is safe in production, then shows you how to turn it on in Promptise Foundry with one argument and measure your real hit rate before you commit.

Should an AI Agent Approve Its Own Action?

Separation of duties for AI agents is the rule that the principal who requests a sensitive action can never be the one who approves it — and it is exactly the control that quietly collapses the moment whoever drives an agent can also click "approve" on the agent's own request. Most human-in-the-loop wiring stops one step short of this. It pauses before a risky tool call and asks a human to decide, which feels like dual control. But if the human answering the prompt is the same person (or the same service identity) that triggered the call, you have a rubber stamp with extra latency, not a second set of eyes. This post goes past the two sentences a general approval overview can spare and works through what dual control actually means, why the reviewer has to be a different principal, and how Promptise Foundry makes reviewer client_id != caller client_id a server-enforced default instead of a policy you hope everyone remembers to build.

Approve in the Agent or the MCP Server? Or Both

The server-side vs agent-side ai approval decision is the one most teams get wrong by not knowing they had a decision to make — they wire a single human-in-the-loop hook, wherever the docs put it, and assume that one hook is doing two jobs it can't do at once. Promptise Foundry ships two distinct enforcement layers for a reason, and this post puts them side by side so you can map each sensitive tool to the layer it actually belongs in.