SaaS Security: Key Steps to Secure API Integrations on Static Frontends
Written by Marcus Aurel
Published on June 20, 2026 • Technical Architecture Guide
Key Architecture Takeaways
Secure your environment variables, manage proxy endpoints, and avoid leaking critical private keys to clients in static site builds.
We almost shipped a major security mistake last year. The kind where a private API key ends up in the browser's network tab, visible to anyone who opens DevTools. It wasn't malicious — it was just a developer who didn't know the difference between server-side and client-side in Astro. The fix took 10 minutes. The realization that it had been exposed for 3 weeks was uncomfortable.
This is our guide to not making that mistake.
The Core Problem: Static Sites Have No Server Secrets
When you build a fully static site (Astro with output: 'static', Next.js exported, Gatsby), everything gets bundled at build time. Any API key you include in client-side JavaScript is visible to anyone who looks at your source code. End of story.
The rule is simple: any secret that should not be public must never touch client-side code.
Mistake 1: Using Private Keys in Astro Client-Side Components
In Astro, components with client:load or client:visible are React/Vue/Svelte components that run in the browser. If you pass a secret key as a prop or import it inside these components, it ships to the browser.
// WRONG - this key will be visible in the browser bundle
const MyWidget = () => {
const data = await fetch('https://api.service.com', {
headers: { 'Authorization': 'Bearer ' + import.meta.env.MY_SECRET_KEY }
});
}
// RIGHT - do this in the .astro file frontmatter (server-side only)
---
const response = await fetch('https://api.service.com', {
headers: { 'Authorization': 'Bearer ' + import.meta.env.MY_SECRET_KEY }
});
const data = await response.json();
---
<MyWidget data={data} />
Mistake 2: Exposing Keys via Client-Side Fetch in Static Sites
If you need real-time data (search, user-specific content), you cannot handle it in a static build. Your options:
- Serverless functions (Vercel Functions, Netlify Functions) — proxy the API call server-side, return only what the client needs
- Astro hybrid rendering — mark specific routes as
prerender: falseto enable SSR for those pages while keeping the rest static - Third-party managed services — some APIs (Algolia, Typesense) provide client-safe keys with restricted permissions
Securing Environment Variables
In Astro, prefix your secrets with nothing (or SECRET_) — they'll only be available server-side. Variables prefixed with PUBLIC_ are intentionally exposed to the browser. This is a useful convention, but developers need to understand the distinction.
On Vercel/Netlify: use the environment variable UI, never commit secrets to your repository. Even in a private repo, secrets in version control are a liability — repo access gets shared, forked, logged.
A Quick Audit Checklist
- Open DevTools Network tab — filter for API calls. Check the request headers. Are any sensitive tokens visible?
- Search your built
dist/folder for your secret key strings. If you find them, something is wrong. - Check your
.envfiles — is.env.localin your.gitignore? - Review any client-side components that make fetch calls. Where do the credentials come from?
Security in static sites is mostly about understanding the boundary between build-time (server) and runtime (browser). Once that's clear, most mistakes are preventable.
Alex Sterling
Verified Technical AuthorSenior Solutions Architect & Lead Reviewer
12+ years in cloud infrastructure, microservice architecture, and enterprise iPaaS integrations. Alex evaluates software pipelines, API payloads, and SaaS pricing efficiencies.
Software picks, honestly reviewed —
straight to your inbox.
Every Tuesday we share our latest review, one tool that surprised us, and one that didn't live up to the hype. No filler, no affiliate-first rankings.