Skip to main content
Secrets are a way for agent builders to request sensitive values for agent execution. A great example is API keys that your agent needs to access external services. The secrets extension allows you to demand specific secrets from users. Users can provide these secrets before running the agent, which is why secret fulfillment is optional. We don’t want to bother users unless absolutely necessary. When an agent can’t continue its work without a secret and the user hasn’t provided it beforehand, the agent may request the secret dynamically and, for example, reject the user request if not specified. Once a secret is provided by the user, it’s stored in the platform so subsequent runs don’t need to prompt the user again.
Users can revoke or update the secret at any time through the GUI.

Quickstart

1

Import the Secrets extension

Import the necessary components from the BeeAI SDK secrets extension.
2

Add secrets parameter to your agent

Inject the Secrets extension into your agent function using the Annotated type hint.
3

Define your secret demands

Create SecretDemand objects for each secret your agent needs.
4

Handle secret fulfillment

Check if secrets are provided and request them dynamically if needed.

Basic Secrets Example

Here’s how to add secrets capabilities to your agent:
import os
from typing import Annotated

from a2a.types import Message

from beeai_sdk.a2a.extensions.auth.secrets import (
    SecretDemand,
    SecretsExtensionServer,
    SecretsExtensionSpec,
    SecretsServiceExtensionParams,
)
from beeai_sdk.server import Server

server = Server()


@server.agent()
async def secrets_agent(
    input: Message,
    secrets: Annotated[
        SecretsExtensionServer,
        SecretsExtensionSpec.single_demand(key="SLACK_API_KEY", name="Slack", description="Access to Slack"),
    ],
):
    """Agent that requests a secret that can be provided during runtime"""
    if secrets and secrets.data and secrets.data.secret_fulfillments:
        yield f"Slack API key: {secrets.data.secret_fulfillments['SLACK_API_KEY'].secret}"
    else:
        runtime_provided_secrets = await secrets.request_secrets(
            params=SecretsServiceExtensionParams(
                secret_demands={"SLACK_API_KEY": SecretDemand(description="I really need Slack Key", name="Slack")}
            )
        )
        if runtime_provided_secrets and runtime_provided_secrets.secret_fulfillments:
            yield f"Slack API key: {runtime_provided_secrets.secret_fulfillments['SLACK_API_KEY'].secret}"
        else:
            yield "No Slack API key provided"


def run():
    server.run(host=os.getenv("HOST", "127.0.0.1"), port=int(os.getenv("PORT", 8000)))


if __name__ == "__main__":
    run()

How to work with secrets

Here’s what you need to know to add secrets capabilities to your agent: Import the secrets extension: Import SecretsExtensionServer, SecretsExtensionSpec, SecretDemand, and SecretsServiceExtensionParams from beeai_sdk.a2a.extensions.auth.secrets. Inject the extension: Add a secrets parameter to your agent function using the Annotated type hint with SecretsExtensionServer and SecretsExtensionSpec. Define your secret demands: Create SecretDemand objects for each secret your agent needs, specifying the name and description. Check for pre-configured secrets: Always check if secrets are already provided before requesting them dynamically. Request secrets dynamically: Use await secrets.request_secrets() to ask for secrets during runtime if they weren’t provided beforehand. Handle missing secrets: Implement appropriate fallback behavior when secrets are not available.
Secrets are securely stored in the platform and automatically provided to your agent on subsequent runs, so users only need to provide them once.
Always check if the secrets extension is available before using it to comply with plain A2A clients.

Usage Patterns

There are two main patterns for working with secrets in your agents:

Pre-configured Secrets

When secrets are provided before the agent runs, they’re available immediately in the secrets.data.secret_fulfillments object. This is the preferred approach as it provides a smoother user experience.
# Check if secrets are pre-configured
if secrets and secrets.data and secrets.data.secret_fulfillments:
    api_key = secrets.data.secret_fulfillments['default'].secret
    # Use the secret immediately

Dynamic Secret Requests

When secrets aren’t pre-configured, you can request them during runtime using await secrets.request_secrets(). This is useful when your agent needs to ask for secrets based on user input or when the secret requirement is conditional.
# Request secrets dynamically
runtime_secrets = await secrets.request_secrets(
    params=SecretsServiceExtensionParams(
        secret_demands={"default": SecretDemand(description="API key needed", name="API Key")}
    )
)