Learn Hermes AI Agent - Secure Agent Deployments
Episode 12 of 23

Learn Hermes AI Agent - Secure Agent Deployments

This episode covers secure agent deployment: choosing a cloud or edge target, managing secrets with external storage, setting up network policies and service authentication, and ensuring HTTPS and secure webhook endpoints in production.

AI Agent
AI AgentAugust 3, 2026
0 views
5 min read

Introduction

In episode 11 you secured the inside of the agent: restricting tool access, storing API keys safely, and building an audit trail with policy enforcement. Now the problem shifts: the agent that used to live on a local machine must move to the cloud or edge, and there it becomes part of infrastructure that anyone could attack. Episode 12 takes you from "a correct agent" to "a correct agent that is also secure in production".

Here is the roadmap for this episode: choosing a cloud or edge deployment target, managing secrets with external storage, setting up network policies and service authentication, and then ensuring HTTPS and secure webhook endpoints.

Choosing a Deployment Target: Cloud or Edge

Before arranging security, first decide where the agent lives. This choice determines the attack surface:

  • Cloud (server/container) — easy to scale, with a mature security ecosystem (IAM, VPC, monitoring). Suited for agents with many tools and unpredictable traffic.
  • Edge — close to the user, low latency, data can be processed locally. Suited for agents handling sensitive data that must not leave the region, but resources are limited and patching is harder.

What matters is not which one is "most secure", but which one fits your workload. An agent holding patient data clearly must not be placed on someone else's edge device without strict sandboxing; a product recommendation agent is actually comfortable at the edge because latency is critical.

Whatever the target, one principle still applies: run the agent as a non-root user, inside a container that has no excessive privileges.

Dockerfile - agent image without root
FROM node:22-alpine AS runtime
WORKDIR /app
COPY out ./out
COPY package.json bun.lock ./
RUN bun install --production
USER node
EXPOSE 3000
CMD ["bun", "run", "start"]

With USER node, the agent process has no permission to write to system directories. If the container is compromised, the attacker does not immediately have root access to the host. Build and test the image locally first before pushing it to the registry with docker build -t agent-image ..

Secrets Management

The lesson from episode 11: never put the actual secret values in code or in the image. Those values must come from the environment at runtime. But in production, putting everything in environment variables is also not enough — anyone who can open the container can read them.

Use external secrets storage and injection at deploy time:

  • Cloud-native: AWS Secrets Manager, GCP Secret Manager, or Azure Key Vault.
  • Self-hosted: OpenBao or Vault (see the secret management series on this blog).
  • Kubernetes: external-secrets to synchronize secrets from a vault into the cluster.

The template you commit to the repository only stores the variable names:

.env.example - names only, not values
HERMES_AGENT_ID=agent-checkout
LLM_API_KEY=
DATABASE_URL=
WEBHOOK_SECRET=
OBSERVABILITY_TOKEN=

When the container runs, the values are filled in by the orchestrator or init process. Rotation also becomes much easier: change the value in the vault, restart the agent, no code changes. For the secrets the agent uses to call LLM providers, also consider scoped keys — tokens that may only call one endpoint and have their own quota.

Warning

Never build secrets into the image, including as build args. The image can sit in the registry for months, and baked-in secrets will leak to anyone with access to the registry.

Network Policies & Service Authentication

An agent in production must not be able to chat with everyone. Limit who can call it, and where it may go.

Network policies in Kubernetes govern the direction and destination of traffic. Example: the agent may only egress to port 443 (HTTPS) and is forbidden from reaching internal IPs:

network-policy.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: agent-egress
spec:
  podSelector:
    matchLabels:
      app: hermes-agent
  policyTypes: ["Egress"]
  egress:
    - to:
        - ipBlock:
            cidr: 0.0.0.0/0
            except:
              - 10.0.0.0/8
              - 192.168.0.0/16
              - 169.254.0.0/16
      ports:
        - port: 443
          protocol: TCP

This also blocks SSRF: if the agent has a tool that fetches URLs, it cannot sneak into the metadata service (169.254.169.254) because link-local IPs are in the exception list.

Service authentication ensures the caller is genuinely authorized. Two common layers:

  • mTLS — both sides prove their identity with certificates. Good for internal service-to-service communication (agent to tool services).
  • Token / per-service API keys — every consumer of the agent (bot, dashboard, other services) is given its own credential that can be revoked and traced.

Never leave the agent openly exposed on the internal network just because "it is safe inside the VPC". One compromised container is enough to hit the whole cluster.

Enforcing HTTPS

All traffic in and out of the agent must be encrypted. HTTPS is no longer optional; plain HTTP means anyone on the network can read the agent's conversation — including prompts that may contain user data.

Two things to pay attention to:

  1. Terminate TLS at the reverse proxy — Caddy, nginx, or a service mesh. The agent itself focuses on logic; TLS is handled at the front layer.
  2. Redirect all HTTP traffic to HTTPS and reject non-TLS requests when possible.

If you receive traffic from the internet, also use an origin allowlist and a body size limit to block suspicious requests before they reach the agent:

proxy-config.yaml
ingress:
  tls:
    enabled: true
  rateLimit: 100
  windowSeconds: 60
  allowedOrigins:
    - https://app.example.com
  maxBodyBytes: 1048576

Secure Webhook Endpoints

Agents are often the receiving side of webhooks — for example, events from a payment gateway or CI. A webhook can be called by anyone who knows the URL, so you must prove the sender is genuine. The standard: an HMAC signature in the header, computed from the raw body and a shared secret.

webhook.ts - HMAC verification
import crypto from "node:crypto";
 
export function verifyWebhook(rawBody, signature, secret) {
  const expected = crypto
    .createHmac("sha256", secret)
    .update(rawBody)
    .digest("hex");
  const a = Buffer.from(signature ?? "");
  const b = Buffer.from(expected);
  return a.length === b.length && crypto.timingSafeEqual(a, b);
}

Important point: verification must be done on the raw body before JSON parsing, because parsing changes the string representation and the signature will no longer match. Use timingSafeEqual for the comparison — not plain === — so an attacker cannot guess the secret through a timing attack. Also make sure webhook events are idempotent: reprocessing the same event must not duplicate its effects.

Info

If your webhook provider sends many events, also store the eventId and reject duplicate events. This prevents double effects when the provider retries because of a timeout.

Conclusion

Episode 12 brought your agent out of the laptop and into real infrastructure. You chose between cloud and edge based on your needs, run the agent as a non-root user, moved secrets to external storage, restricted egress and callers with network policies and service authentication, enforced HTTPS, and protected the webhook endpoint with secure HMAC verification.

Key takeaways:

  • The attack surface differs between cloud and edge — choose the target based on your workload, not trends.
  • Secrets live in external storage, not in the image or an environment anyone can read.
  • Network policies restrict egress and at the same time close the SSRF hole into the metadata service.
  • Service authentication is mandatory, including between internal services — do not trust "safe inside the VPC".
  • Webhooks must be verified with HMAC over the raw body and compared using timingSafeEqual.

In the next episode 13 we turn to the user side: User Authentication & Persona — multi-user scenarios, per-user agent behavior, persona and role-based access, and user data privacy. See you there!