惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

D
DataBreaches.Net
N
Netflix TechBlog - Medium
P
Proofpoint News Feed
D
Docker
J
Java Code Geeks
L
LangChain Blog
Microsoft Security Blog
Microsoft Security Blog
The GitHub Blog
The GitHub Blog
I
InfoQ
Stack Overflow Blog
Stack Overflow Blog
云风的 BLOG
云风的 BLOG
Engineering at Meta
Engineering at Meta
MongoDB | Blog
MongoDB | Blog
月光博客
月光博客
T
Tailwind CSS Blog
M
MIT News - Artificial intelligence
Blog — PlanetScale
Blog — PlanetScale
Google DeepMind News
Google DeepMind News
腾讯CDC
罗磊的独立博客
U
Unit 42
爱范儿
爱范儿
Vercel News
Vercel News
MyScale Blog
MyScale Blog

DEV Community

Authentication Security Deep Dive: From Brute Force to Salted Hashing (With Java Examples) Why AI Systems Don’t Fail — They Drift Spilling beans for how i learn for exam😁"Reinforcement Learning Cheat Sheet" I Replaced Chrome with Safari for AI Browser Automation. Here's What Broke (and What Finally Worked) How Python Borrows Other People's Work The $40 Architecture: Processing 1 Billion API Requests with 99.99% Uptime Vibe Coding: A Workflow Guide (From Zero to SaaS) Most webhook security guides protect the wrong side. The scary part is delivery. Headless CMS for TanStack Start: Build a Blog with Cosmic EU Age Verification App "Hacked in 2 Minutes" — What Actually Happened Comfy Cloud’s delete function does not actually remove files Running AI Models on GPU Cloud Servers: A Beginner Guide Event-driven media intelligence with AWS Step Functions and Bedrock I scored 500 AI prompts across 8 quality dimensions — here's what broke How to Call Google Gemini API from Next.js (Free Tier, No Backend Needed) The Portal Protocol: Reclaiming Human Connection in the Age of AI How to Fix Your Team's Scattered Knowledge Problem With a Self-Hosted Forum Intro to tc Cloud Functors: A Graph-First Mental Model for the Modern Cloud Designing Multi-Tenant Backends With Both Ownership and Team Access I Built a Neumorphic CSS Library with 77+ Components — Here's What I Learned PostgreSQL Performance Optimization: Why Connection Pooling Is Critical at Scale Cómo construí un SaaS multi-rubro para gestionar expensas en Argentina con FastAPI + Vue 3 🚀 I Built an Ethical Hacking Scanner Tool – Open Source Project I Replaced /usage and /context in Claude Code With a Single Statusline A Pythonic Way to Handle Emails (IMAP/SMTP) with Auto-Discovery and AI-Ready Design I Collected 8.9 Million Polymarket Price Points — Here's What I Found About How Markets Really Move EcoTrack AI — Carbon Footprint Tracker & Dashboard Everyone's Using AI. No One Agrees How. 5 self-hosted ebook managers worth trying in 2026 Building Your First AI Agent with LangChain: From Chatbot to Autonomous Assistant
Your .env file should have one line
Arvin Gopi · 2026-05-03 · via DEV Community

Every AI app I've shipped recently rewrote the same plumbing. The OAuth dance for Slack. Encrypted storage for an API key. Refresh-token logic that finally fails on the 3rd call after an hour. Wiring up an MCP client to a server behind a bearer token someone pasted into a Notion page.

I'd write it, copy-paste it into the next app, watch it rot. Each new agent built by a different teammate, slightly differently, with slightly different bugs. We were a small team and the integration code became most of the code.

## The pattern under all of it

Strip away the providers and the AI-specific bits, and every app needed the same four things from the platform:

  1. Env vars — a database URL, a Stripe key, the boring stuff. Not in a .env file in a Docker image. Not in a CI secret. Somewhere the app can ask for at runtime.
  2. Pre-built integrations — Gmail, Calendar, Drive. The user logs in once on the platform; every app gets typed access on their behalf.
  3. Custom OAuth — the providers no platform pre-builds. Slack, Notion, the company's SSO. The customer holds the client_id/secret; their app shouldn't.
  4. Custom MCP — internal MCP servers, third-party MCPs. The customer holds the URL and the bearer token; their app shouldn't.

That's the spine of the SDK we ended up shipping. Four primitives, every app uses some of them, none of them require integration code in the app.

## Register once at the org level

The flip is registration. The org owner registers their things one time on the dashboard:

  • Drop a Slack client_id + client_secret into the "Custom OAuth providers" card. Encrypted with the org's KMS key. The app never sees it.
  • Drop the URL of an internal MCP server + a bearer token into the "Custom MCP servers" card. Same treatment.
  • Connect Doppler / 1Password / GCP Secret Manager as a secret source — or just type secrets into the dashboard.

Now every app you deploy in that org gets typed access through four SDK calls.

## The four calls

  import { LeashIntegrations } from '@leash/sdk/integrations'                                                                                                                                                                                             

  const client = new LeashIntegrations({ apiKey: process.env.LEASH_API_KEY })                                                                                                                                                                             

  // 1. Env var (resolves through your configured secret source)                                                                                                                                                                                          
  const dbUrl = await client.getEnv('DATABASE_URL')                                                                                                                                                                                                       

  // 2. Pre-built integration                                                                                                                                                                                                                             
  const messages = await client.gmail.listMessages({ maxResults: 5 })                                                                                                                                                                                     

  // 3. Custom OAuth — fresh access token for any provider you've registered                                                                                                                                                                              
  const slackToken = await client.getAccessToken('slack')

  // 4. Custom MCP — { url, headers } including bearer Authorization                                                                                                                                                                                    
  const mcp = await client.getCustomMcpConfig('acme-tools')                                                                                                                                                                                               

Enter fullscreen mode Exit fullscreen mode

Same shape across TypeScript, Python, Go, Ruby, Rust, and Java. No client_secret in the app code. No refresh-token handler. No MCP boilerplate.

## Your .env collapses to one line

The thing we noticed only after living with it: once you're using this, the only secret your app's .env actually needs is the platform API key.

  # .env  (yes, this is the whole thing)                                                                                                                                                                                                                  
  LEASH_API_KEY=lsk_live_...                                                                                                                                                                                                                              

Enter fullscreen mode Exit fullscreen mode

That's it. No more .env.example drift. No more "did we set DATABASE_URL in staging?" debugging at 11pm. Rotation happens at the source — no rebuild, no redeploy.

## What it deliberately doesn't do

A few decisions that came up that I'll defend:

Doesn't proxy MCP traffic. We hand the app {url, headers} (with bearer Authorization already attached) and the app calls the MCP directly. Leash isn't in the request path. Tool calls are on the LLM's critical path; an extra hop hurts. We also
didn't want to reimplement every MCP transport (streamable HTTP, SSE, stdio) with our own bugs.

Doesn't force you to use the platform for secrets. If you'd rather hold them in Doppler or 1Password, point the platform at your existing source. getEnv resolves through whichever the org configured.

Doesn't pretend to be multi-cloud. Single-region GCP today. If you're betting on us, you're betting on a small surface area — not a multi-cloud promise.

## The why behind the shape

Customer apps can't hold credentials safely. Their AI agent runs on someone's laptop, in CI, on a Cloud Run revision someone's about to redeploy. Putting client_secret in the app means rotating it everywhere whenever it leaks. So we put the

credential in one place and gave the app a thin retrieval call instead.

Same logic for MCP. The bearer token for a customer's internal tool server isn't something we want their AI app to know. The app gets a config dictionary right before it calls the MCP. That's as long as the credential lives anywhere near user code.

The four-primitive surface area is small on purpose. Anything else (token caching, retries, pagination on Gmail, etc.) lives in the SDK or in the customer's code, not in the platform contract. We'd rather grow the SDK than the API.

## Try it

  curl -fsSL https://leash.build/install.sh | sh                                                                                                                                                                                                        
  leash login                                                                                                                                                                                                                                             
  leash deploy                            

Enter fullscreen mode Exit fullscreen mode

Or just sign up at leash.build, register a Slack app or an internal MCP, and call the SDK from any project. Custom OAuth + custom MCP are gated to the Growth plan; built-in integrations work on every plan including free.

Curious what others have done for this. Especially the proxy-vs-config-handoff call for MCP — I made the bet, but it's the architecture choice I'd most welcome a counterargument on.