Securing your container: basic auth and IP rules
When you publish a container to the public internet, you usually want some control over who can reach it. A staging deployment shouldn't be open to crawlers and script kiddies. An internal admin panel shouldn't accept traffic from random IPs. A production API shouldn't be one zero-day away from total compromise just because the application library got patched late.
Bahriya gives you three primitives at the ingress for HTTP containers, and you can combine them however you like:
- Basic authentication — every request must present a valid username/password.
- IP allow-list — only listed IPs/CIDRs can reach the container; everything else is rejected.
- IP deny-list — listed IPs/CIDRs are blocked; everything else gets through.
All three are configured on the container itself and applied at the Kong ingress that fronts every HTTP container on Bahriya. They run before your application receives the request, so a blocked IP or a missing credential never costs your container a CPU cycle.
This article walks through when to reach for each, how they interact, and the practical tradeoffs.
Basic auth: the simplest credential gate
HTTP Basic Authentication is the oldest credential mechanism on the web. The client sends Authorization: Basic base64(username:password) on every request; the server either accepts it or returns 401 Unauthorized. No cookies, no sessions, no flows — just a header.
It's the right tool when:
- You need to gate a staging environment from public eyes.
- You're exposing a dashboard or internal tool that doesn't have its own login.
- You want a temporary credential gate while you build out proper SSO.
- You're sharing a non-production deployment with a customer or partner who shouldn't see the code-signing prompts of OAuth or SAML.
It's the wrong tool when:
- You need per-user audit trails, MFA, or session timeout.
- You want to integrate with an identity provider.
- The credential must be revocable per-device without invalidating other users.
On Bahriya, enabling basic auth is a toggle in the container's Security section. When you turn it on, you add up to 10 username/password pairs. Each pair is independent — any of them can authenticate, and removing one only affects requests using that specific credential.
How Bahriya stores the passwords
When you save a password, it's AES-256 encrypted in the database before it's written. The plaintext value isn't kept anywhere on the API side. At deploy time, the pipeline decrypts the password and hands it to Kong as a credential on a Kubernetes Secret, scoped to your project's namespace and used only by the basic auth plugin.
The corollary: you cannot read your passwords back. The console shows existing credentials with the username visible but the password input pre-filled with placeholder dots. You can rotate a password by typing a new value, you can remove a credential entirely, or you can leave the row untouched to keep the existing password. There is no "show password" or "recover password" — if a user forgets theirs, you set a new one and share it again.
This is a deliberate choice. A password you can read back from the platform is a password an attacker who steals your console session can read too. One-way storage means a compromise of the console doesn't automatically compromise every protected container.
See Basic Authentication for the full details on configuration and the username rules.
IP allow-list: only these IPs can reach the container
An IP allow-list flips the default from "open to everyone" to "open only to these addresses." When enabled, Bahriya rejects every request from an IP outside your list, before the request reaches your application.
This is the right tool when:
- Your container is an internal service that should only be reachable from your office network, your VPN, or your bastion host.
- You're running a webhook receiver that only needs to accept calls from a known vendor's published IP ranges.
- You're in a regulated environment that requires a documented set of allowed source addresses.
The list supports both individual IPs (203.0.113.10) and CIDR ranges (10.0.0.0/8, 2001:db8::/32). One entry per line.
A few traps to watch for:
- You can lock yourself out. If you allow only your office IP and your office IP changes, you lose access. Keep an emergency channel — VPN, a colleague's IP, your home IP — in the list during transitions.
- Behind a proxy or CDN, the client IP your container sees is the proxy's IP, not the original requester. Bahriya's ingress preserves the original client IP via
X-Forwarded-For, but if you sit behind another layer (CloudFlare, a corporate gateway), make sure the IP you're allow-listing is the one Kong actually sees.
- Mobile and home users have rotating IPs. Allow-listing humans by IP works for offices and data centers, not for individuals on residential broadband.
IP deny-list: block specific IPs while keeping everything else open
An IP deny-list is the inverse: traffic flows freely except from listed addresses. When enabled, Bahriya rejects requests from any IP in the list and lets the rest through.
This is the right tool when:
- You're under attack from a small set of identifiable sources and need to block them immediately.
- You've spotted abuse from known bad actors and want to keep them out while your application stays open to legitimate traffic.
- A vendor or scanner is hitting your container with excessive traffic and ignoring
robots.txt.
It's the wrong tool for general access control — for that, use an allow-list or basic auth. A deny-list assumes you can enumerate the bad actors faster than they appear. That's true for narrow, targeted abuse; it isn't true for botnets or distributed scanners.
You can find both lists in the Security section of the container form. See Rate Limiting and IP Rules for the full reference.
How they combine
Bahriya evaluates the layers in a fixed order at the ingress:
- IP deny-list runs first. If the requester is on it, Kong returns
403 Forbidden and stops.
- IP allow-list runs second. If enabled and the requester is not on it, Kong returns
403 Forbidden and stops.
- Rate limiting runs third. If the requester has exceeded their per-minute or per-hour budget, Kong returns
429 Too Many Requests and stops.
- Basic auth runs last. If the request doesn't carry a valid
Authorization header, Kong returns 401 Unauthorized and stops.
Only requests that survive all four layers reach your application.
This ordering has practical consequences:
- Rate limiting throttles brute-force attempts on basic auth credentials. Because rate limiting runs before basic auth, a client trying to guess your password gets throttled before Kong even checks the credential. You can leave basic auth enabled and rely on rate limiting to keep brute-force costs high.
- An allow-listed IP still needs valid credentials. Combining an allow-list with basic auth gives you "only these networks can even attempt to authenticate, and they need a valid credential to succeed." That's a sensible default for an internal admin tool: scope by network first, then identity.
- A deny-listed IP never sees a credential prompt. You won't accidentally leak information about which IPs you've blocked just by watching for
401s — they'll all get 403.
Practical recipes
Here are four configurations that cover most of what most teams need.
Staging environment, only your team can see it
- Basic auth enabled, one credential per team member (up to 10).
- No IP allow-list.
- Optional rate limit: 60 requests per minute, to keep brute-force costs high.
Result: anyone on the internet can knock on the door, but only your team has the keys.
Internal admin panel, office-only
- IP allow-list enabled, your office and VPN IPs in the list.
- Basic auth enabled, one credential per admin (rotate quarterly).
- Rate limit: 120 requests per minute.
Result: only your network can even reach the panel, and anyone who does still needs valid credentials.
Public API under attack from a botnet of three IPs
- IP deny-list enabled, the three offending IPs listed.
- Rate limit: 1000 requests per hour per IP, to slow down anything else that gets out of hand.
- No basic auth (the API is public by design).
Result: known bad actors blocked immediately; the rest of the internet keeps working.
Customer-facing webhook receiver
- IP allow-list enabled, the vendor's published webhook IPs in the list.
- No basic auth (the vendor signs requests with HMAC and your application validates the signature).
- Rate limit: high, e.g. 600 requests per minute.
Result: only the vendor's infrastructure can deliver webhooks; signature validation in your application handles authentication of individual events.
Changes take effect on the next deployment
When you toggle basic auth, rotate a password, edit an IP list, or change rate limits, Bahriya rolls out a fresh ingress configuration as part of the container's next deployment cycle. Deployments are rolling and have zero downtime — existing connections drain naturally, new ones land on pods with the updated configuration. The full cycle typically completes in under a minute.
If you're locking down a container that's already in production, this means there's a small window where some pods have the new rules and some have the old. Plan accordingly: don't flip an allow-list on a live customer-facing endpoint without first verifying your own IP is in the list.
Where to go from here