Add Secrets to Connect to Third Party Providers

Secrets securely manage sensitive information, such as API keys, and allow connections to third-party service providers that require authentication. They're especially useful for handling development and production API keys or when building custom components that need to authenticate with a third-party provider.

About This Task

With secrets, you can:

  • Securely manage API keys required for custom components to authenticate without hard coding them in pipeline YAMLs.
  • Manage both development and production API keys.

Secrets create environment variables whose names you specify in the component's code to store API keys. You can create multiple secrets for one provider, such as one for a development key and another for a production key. This makes it possible to easily swap keys in the pipeline configuration.

Secrets and Connections

Both Connections and Secrets set environment variables for components. Provider connections use predefined variables, like OPENAI_API_KEY for the OpenAIGenerator. Secrets offer flexibility by letting you define custom variable names, which are useful for custom components or using multiple API keys for the same provider.

Add a Secret

Add a Secret on the Secrets Page

  1. In deepset Cloud, click your initials in the top right corner and choose Secrets>Add New Secret.

  2. Give your secret the same name as the environment variable where you want to store it.

  3. Paste the API key into the Secret field and save it.

Use the Secret in Your Custom Component

Add the secret to your component's code:

  • Make sure you import it.
  • Specify the environment variable name, which must match the secret's name.
  • Add its serialization and deserialization methods.
  • Add a warm_up() method to load the API key before pipeline validation. This step is optional but we recommend it:

from haystack import component, default_from_dict, default_to_dict
from haystack.utils import Secret, deserialize_secrets_inplace
from typing import Any, Dict


@component
class MyComponent:
    def __init__(self, model_name: str, api_key: Secret = Secret.from_env_var("ENV_VAR_NAME")):
        self.model_name = model_name
        self.api_key = api_key
        self.backend = None

    def warm_up(self):
        # Call api_key.resolve_value() to load the API key from the environment variable
        # We put the resolution in warm_up() to avoid loading the API key during pipeline validation
        if self.backend is None:
            self.backend = SomeBackend(self.model_name, self.api_key.resolve_value())

    def to_dict(self) -> Dict[str, Any]:
        # Make sure to include any other init parameters in the to_dict method
        return default_to_dict(
            self,
            model_name=self.model_name,
            api_key=self.api_key.to_dict(),
        )

    @classmethod
    def from_dict(cls, data: Dict[str, Any]) -> "MyComponent":
        # Make sure to use deserialize_secrets_inplace to load the Secret object
        init_params = data.get("init_parameters", {})
        deserialize_secrets_inplace(init_params, keys=["api_key"])
        return default_from_dict(cls, data)

    def run(self, my_input: Any):
        if self.backend is None:
            raise RuntimeError("The component wasn't warmed up. Run 'warm_up()' before calling 'run()'.")
        return self.backend.process(my_input)

If you have multiple secrets for one provider, you can easily switch between them in your pipeline YAML by updating the secret's name:

llm:
  type: dc_custom_component.components.my_components.component1.MyComponent # the path to your component
  init_parameters:
     api_key: {"type": "env_var", "env_vars": ["ENV_VAR_NAME"], "strict": False} # uses the `ENV_VAR_NAME` secret
     # to use another secret, update its name here