Short answer: keep the AI provider's API key in the server's environment, and never send it to the browser. The browser asks your Drupal site for a short-lived, signed session; Drupal mints it with the key and hands over only the session. Callbacks from the provider are checked by signature, the tools the agent can call check a secret, and what the agent writes waits for a person. Our own site's voice concierge works this way, on elevenlabs_agent, a module our founder created and maintains on drupal.org. The module is in its 1.0 alpha series: published and actively maintained.
Why do so many AI chatbots expose their keys?
Because the quickest way to add a chatbot is a widget that talks to the AI provider straight from the visitor's browser. For that, the browser needs a credential, and anything a browser holds, a visitor can read in the developer tools. A key read that way works for whoever has it, and the bill goes to you. Keeping the key on the server is ElevenLabs' own requirement for its agents, as the module's documentation notes.
How does the agent keep its key on the server?
Here is how elevenlabs_agent does it in its current release, 1.0.1-alpha12 of 7 October 2026:
- A visitor presses the call button. The browser asks a Drupal route for a session. The route checks a security token and a rate limit first.
- Drupal calls the provider with the key, which only the server holds, and gets back a short-lived, signed session.
- The browser receives only that session and opens the live audio connection with it. The key never leaves the server.
- When the call ends, the provider sends the transcript back to Drupal. Drupal checks its HMAC-SHA256 signature and its timestamp before believing a word of it.
- If the agent calls one of the site's tools during the conversation, the tool's endpoint checks a shared secret first.
On our own site, the agent's three secrets (the API key, the callback secret and the tool secret) come from the server's environment. The configuration committed to git holds them empty. That is what the module's security guide asks for: secrets in settings overrides, never in exportable configuration, and Drupal's status report warns when they are not.
Why it matters to you: you can hand the repository to a new developer, export the configuration or open the browser's developer tools, and the key is in none of them.
What can the agent actually do?
Only what its tools allow. Each tool has a name, a description and a schema, and Drupal answers the call. Our rule for the concierge is that it answers only from what the site publishes. It has one tool that writes: when a visitor has said enough, it saves a lead. That lead is saved unpublished, like a contact-form submission, for a person to read and decide on. The agent does not publish it, email it or act on it.
The module is also careful with the rest of the site. It never starts a Drupal session for an anonymous visitor (the list of pages a visitor has read stays in their browser and travels with the call), so pages stay cacheable.
Why it matters to you: an agent's risk is the list of things it can do. Keep the list short, and make every write something a person reviews.
How do you keep the bill predictable?
By limiting who can start a call, and by watching what each call costs. What the module does today:
- Rate limits on new sessions: per visitor address (by default 10 a minute), plus an optional site-wide ceiling and an optional per-agent ceiling, for a crowd of clients that each stay under the per-address limit. Our concierge has the site-wide ceiling switched on.
- A cap on one call's length: 1,200 seconds by default, which our concierge keeps.
- A cost record for every call, stored as the provider reports it, attributed to the agent, and exportable for the accounts.
- A usage meter that shows today's and this month's spend against a budget you set.
That is monitoring and rate limiting, not a cut-off. For a backstop that does not depend on the module, its own README recommends setting account-level usage limits in the provider's dashboard. One more detail matters behind a CDN: the per-address limit only works if Drupal sees each visitor's real address. On our sites, behind Cloudflare, it does.
What about privacy?
A voice agent records people, so decide this per agent, before launch:
- Whether calls are recorded. The transcript is what a lead is made from.
- How long the provider keeps them. Our concierge keeps them 90 days, and our privacy policy says so. The module's documentation notes that the provider's own default is to keep them forever.
- Consent. The call button asks for microphone and sound permission the first time it is used.
Why it matters to you: these are three settings, and each one is a sentence your privacy policy has to match.
Where do Drupal's own AI modules fit?
"Drupal AI agents" is also the name of a module. Drupal's community builds its general AI framework in the AI module (ai, 1.5.1, released 14 October 2026) and the AI Agents module (ai_agents, 1.3.5, with 1.4.0-beta1 in testing, both released 2 September 2026). elevenlabs_agent is a different piece: a live voice agent that stands alone and does not depend on the AI module. Our own site does not run the AI module today. The rule about keys is the same for both: the key belongs to the server, and the browser gets only what one session needs.
If what you want is for your own assistant to work on the site, rather than a visitor talking to an agent, that is an MCP server: see an MCP server for a Drupal site.
What we don't claim
- The module is in its 1.0 alpha series. Its own security document says it is pre-release and not yet covered by drupal.org's security advisory policy.
- That document also lists its known limits, such as no replay protection on tool calls beyond rotating the tool secret. We would rather you read that here than find it later.
- Its README says plainly that it is heavily AI-assisted and human-reviewed. How we work with AI is in how we use AI, and where we don't let it act.
- We don't publish our concierge's numbers.
- Today the engineer is our founder. Support runs in business hours, Colombian time (UTC-5), and the one fixed price is an hour of the founder's time: USD 75.
The concierge on our home page is this module, running. Ask it something, or write to us. For an agent on your own site, see what we offer.