Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
93 changes: 22 additions & 71 deletions pages/home/build-tools/create-a-tool-with-secrets.mdx
Original file line number Diff line number Diff line change
@@ -1,102 +1,53 @@
---
title: "Adding secrets to your tools"
title: "Create a tool with secrets"
description: "Learn how to build custom tools that require secrets using Arcade"
---

import { Steps, Tabs } from "nextra/components";

# Adding secrets to your tools
# Create a tool with secrets

In this guide, you'll learn how to add secrets to your custom tools, using Arcade.
In this guide, you'll learn how to use secrets in your custom Arcade tools.

Secrets are sensitive strings like passwords, api-keys, or other tokens that grant access to a protected resource or API.

In this example, you'll create a tool that reads data from a postgres database.
Secrets are sensitive strings like passwords, api-keys, or other tokens that grant access to a protected resource or API. Although you could use secrets to transfer any static information to your tool, such as a parameter needed to call a remote API.

<Steps>

### Prerequisites

- [Set up Arcade](/home/quickstart)
- [Create a toolkit](/home/build-tools/create-a-toolkit)
- [Understand Tool Context](/home/build-tools/tool-context)

We will be using `sqlalchemy` and `psycopg2-binary` to access a postgres database.


<Tabs items={["uv", "pip"]}>
<Tabs.Tab>
```bash
uv pip install arcade-ai sqlalchemy psycopg2-binary
```
</Tabs.Tab>
<Tabs.Tab>
```bash
pip install arcade-ai sqlalchemy psycopg2-binary
```
</Tabs.Tab>
</Tabs>

### Define your tool

Create a new Python file, e.g., `sql_tools.py`, and import the necessary modules:
```python file=<rootDir>/examples/code/home/build-tools/create-a-tool/imports.py
```
### Set the secret in the Arcade Dashboard

Now, define your tool using the `@tool` decorator and specify the needed secrets with `requires_secrets`, in this case a `DATABASE_CONNECTION_STRING`. In this example, `DATABASE_CONNECTION_STRING`, is meant to be a JDBC-style database connection URL, e.g. `postgres://user:[email protected]/database_name`. Our `DATABASE_CONNECTION_STRING` will contain a username and password in this case, making it very sensitive.
Go to the [Auth > Secrets section](https://api.arcade.dev/dashboard/auth/secrets) in the Arcade Dashboard.

```python file=<rootDir>/examples/code/home/build-tools/create-a-tool/sql-tool.py
```
![An image showing how the Arcade UI allows users to manage secrets](/images/docs/secrets/secrets-dashboard-2.png)

### Use your tool with Arcade
In the top-right corner, click the **+ Add Secret** button and enter:

Now you can use your custom authorized tool with Arcade in your application.
- **ID**: `MY_SECRET_INFO`
- **Secret Value**: `my-secret-value`
- **Description**: optionally add a description

Here's an example of how to use your tool. Note that for this example, the table schema includes a `users` table and a `messages` table, and `messsages` has a foreign key back to `users`.
Click **Submit** to save the secret.

<details>

<summary>See full schema</summary>
### Define your tool and access the secret

```sql file=<rootDir>/examples/code/home/build-tools/create-a-tool/schema.sql
```
</details>
Use the `@tool` decorator to define the secret requirement. The `context` object has a `get_secret` method that you can use to access the secret value.

```python
from arcade_tdk import ToolContext, tool

```ts file=<rootDir>/examples/code/home/build-tools/create-a-tool/app.ts.fake
@tool(requires_secrets=["MY_SECRET_INFO"])
def my_tool_using_secret(context: ToolContext) -> str:
secret_value = context.get_secret("MY_SECRET_INFO")
return f"The secret value is {secret_value}"
```

You'll get a response like this:

```bash
⚙️ Found the following tools:
Sql_DiscoverTables: Discover all the tables in the database
Sql_ExecuteQuery: Execute a query and return the results
Sql_GetTableSchema: Get the schema of a table

[🔍] Discovered the following tables: users, messages
[📜] Schema for users: id: int,name: str,email: str,password_hash: str,created_at: datetime,updated_at: datetime
[📜] Schema for messages: id: int,body: str,user_id: int,created_at: datetime,updated_at: datetime


[❓] Asking: Get the first 10 users's IDs and Names
[📝] SQL statement: SELECT id, name FROM users ORDER BY id LIMIT 10;
[ "(1, 'Sam')", "(3, 'Evan')", "(12, 'Wils')" ]

[❓] Asking: Who has sent the most chat messages?
[📝] SQL statement: SELECT u.name, COUNT(m.id) AS message_count FROM users u JOIN messages m ON u.id = m.user_id GROUP BY u.name ORDER BY message_count DESC LIMIT 1;
[ "('Evan', 218)" ]
```
When your tool is executed, it will return: `"The secret value is my-secret-value"`. In a real world application, you would use this secret to connect to a remote database, API, etc.

</Steps>

### Supplying the Secret

Note how in the example above we never provided a value for `DATABASE_CONNECTION_STRING`. This is because we want the Arcade engine to manage this for us, keeping the sercets that the tool needs seperate from the environment that is exceuting the LLM calls (our application above).

Using Arcade Cloud, after publishing your tool with [`arcade deploy`](https://docs.arcade.dev/home/serve-tools/arcade-deploy), you will see that your tool requires the `DATABASE_CONNECTION_STRING` secret:

![An image showing how the Arcade UI displays that our new SQL tools require a secret now](/images/docs/secrets/secrets-dashboard-1.png)

You can manage your secrets from the [`secrets` section](https://api.arcade.dev/dashboard/auth/secrets) of the authentication section:

![An image showing how the Arcade UI allows users to manage secrets](/images/docs/secrets/secrets-dashboard-2.png)