Skip to content
Open
Show file tree
Hide file tree
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
1 change: 1 addition & 0 deletions agents/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ command installs the whole thing.
| [compliance-reviewer](compliance-reviewer) | Reviews PRs against SOC2 / GDPR / your custom compliance rules |
| [cross-org-collab-agent](cross-org-collab-agent) | Privacy by construction — multi-layer field guards for cross-org threads |
| [fde-agent](fde-agent) | Forward Deployed Engineer agent — runs a discovery → implementation → validation → handoff playbook, specialized with your project knowledge |
| [internal-caller-agent](internal-caller-agent) | Demonstrates authenticated outbound API calls with an agent-scoped bearer token |
| [onboarding-qa](onboarding-qa) | Answers new-hire questions from your knowledge base |
| [platform-health-agent](platform-health-agent) | Daily report on repo health, GitHub event alerts, and a 5xx digest from production logs — delivered to Slack |
| [release-notes-bot](release-notes-bot) | Watches merged PRs weekly, drafts changelog as a GitHub issue |
Expand Down
11 changes: 11 additions & 0 deletions agents/internal-caller-agent/.aaignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# Auto-generated by `uv run scripts/sample_tool.py generate` — do not edit.
#
# This sample is installed via `archastro install agentsample <slug>`,
# which reads sample.yaml's `steps:` block and runs the DSL executor.
# `archastro deploy configs` should skip every file inside this
# directory.
README.md
agent.yaml
env.example
sample.yaml
scripts/
119 changes: 119 additions & 0 deletions agents/internal-caller-agent/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
# Internal Caller Agent

## Deploy with your coding agent

Paste this into Claude Code, Codex, or any AI coding assistant:

```
Deploy the Internal Caller Agent from this repo.

1) Read agents/internal-caller-agent/agent.yaml and agents/internal-caller-agent/env.example
2) Install the ArchAgents CLI if missing: brew install ArchAstro/tools/archagent
3) Run: archagent auth login <my-email> && archagent init
4) Deploy: archagent install agentsample internal-caller-agent
5) Create a demo bearer token: TOKEN="$(openssl rand -hex 32)"
6) Set it on the deployed agent: archagent create agentenvvar --agent <agent-id> --key AGENT_BEARER_TOKEN --value "$TOKEN"
7) Test it: create an agent session and ask it to call get_auth_status
8) Confirm the response says authenticated=true, status=200, token_was_echoed=true, and token_matched_secret=true
```

> Demonstrates outbound API authentication with an agent-scoped bearer token.

This sample is intentionally small: one agent, one script-backed custom
tool, and one agent environment variable. The tool calls
`https://httpbin.org/bearer` with:

```bash
curl -sS "https://httpbin.org/bearer" \
-H "Authorization: Bearer $AGENT_BEARER_TOKEN"
```

The token is stored as an agent-scoped secret, so it is available to this
agent's server-side scripts without exposing it in the agent template or
tool arguments.

## What it does

When asked to check auth, the agent calls `get_auth_status`. The script:

1. Reads `env.AGENT_BEARER_TOKEN`
2. Sends it as a bearer token in the `Authorization` header
3. Reads httpbin's response
4. Returns a safe summary:
- `authenticated`
- HTTP `status`
- `token_was_echoed`
- `token_matched_secret`

It does not return the full bearer token.

## Setup

Deploy the sample:

```bash
archagent install agentsample internal-caller-agent
```

Then create the agent-scoped secret. Use the deployed agent ID printed by
the install command:

```bash
TOKEN="$(openssl rand -hex 32)"

archagent create agentenvvar \
--agent <agent-id> \
--key AGENT_BEARER_TOKEN \
--value "$TOKEN" \
--description "Demo bearer token for authenticated outbound request sample"
```

## Test it

Create a short session:

```bash
archagent create agentsession \
--agent <agent-id> \
--instructions "Call get_auth_status once and report the result." \
--wait
```

Expected result:

```text
authenticated: true
status: 200
token_was_echoed: true
token_matched_secret: true
```

## Why agent-scoped secrets

Use agent-scoped environment variables when a credential belongs to one
agent's job. Compared with org-scoped variables, this keeps the blast
radius smaller: another agent in the same org cannot read this token just
because it can run scripts.

For shared credentials, use an org-scoped env var instead and reference it
from multiple agents.

## What this demonstrates

- Script-backed custom tools
- Agent-scoped environment variables
- Bearer-token `Authorization` headers
- Server-side HTTP calls from an agent tool
- Avoiding secrets in tool inputs, templates, and chat transcripts

## Files

```text
internal-caller-agent/
|-- README.md
|-- agent.yaml
|-- env.example
|-- sample.yaml
`-- scripts/
`-- get-auth-status.aascript
```
53 changes: 53 additions & 0 deletions agents/internal-caller-agent/agent.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
kind: AgentTemplate
agent_key: internal-caller-agent
name: Internal Caller Agent
model: openrouter/anthropic/claude-sonnet-latest
description: Demonstrates authenticated outbound API calls from an agent-scoped secret.
identity: |
You are Internal Caller Agent, a concise demo agent for authenticated
outbound API requests.

When a user asks whether your bearer-token authentication is working,
call `get_auth_status` and report:

- whether the request authenticated
- the HTTP status from httpbin
- whether the echoed token matched your agent-scoped secret
- whether httpbin echoed a token

Keep the explanation short and make it clear that the bearer token came
from the agent-scoped `AGENT_BEARER_TOKEN` environment variable. Never
include the full bearer token or a partial token value in your response.

tools:
- kind: custom
name: get_auth_status
description: |
Call httpbin's bearer-token endpoint with the agent-scoped
AGENT_BEARER_TOKEN secret and return the auth result.
parameters:
type: object
properties: {}
required: []
handler_type: script
config_ref: get-auth-status
status: active

routines:
- name: Participate in conversations
description: Join conversations and respond to user messages.
handler_type: preset
preset_name: participate
event_type: thread.session.join
event_config:
thread.session.join:
filters: {}
status: active

metadata:
category: demos
version: "1.0"
demonstrates:
- agent-scoped environment variables
- bearer token authorization headers
- script-backed custom tools
5 changes: 5 additions & 0 deletions agents/internal-caller-agent/env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Required after deploying the agent.
#
# This is intentionally agent-scoped instead of org-scoped so only this
# agent's script-backed tools can read it.
AGENT_BEARER_TOKEN=demo_replace_with_random_token
11 changes: 11 additions & 0 deletions agents/internal-caller-agent/sample.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
schema_version: 2
version: v0.1.0
name: "Internal Caller Agent"
tagline: "Shows how an agent can call an authenticated API with an agent-scoped bearer token."
min_cli_version: "0.28.0"

steps:
- type: upload_scripts
source_dir: scripts
- type: deploy_agent
template_file: agent.yaml
21 changes: 21 additions & 0 deletions agents/internal-caller-agent/scripts/get-auth-status.aascript
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// Demonstrates an authenticated outbound API call with an agent-scoped
// bearer token. The full token is not returned to the agent.

let http = import("requests")

let response = unwrap(http.get("https://httpbin.org/bearer", {
headers: {"Authorization": "Bearer " + env.AGENT_BEARER_TOKEN},
timeout: 30
}))

let echoed_token = response.body.token || ""

{
ok: response.status == 200,
status: response.status,
endpoint: "https://httpbin.org/bearer",
authenticated: response.body.authenticated,
token_was_echoed: echoed_token != "",
token_matched_secret: echoed_token == env.AGENT_BEARER_TOKEN,
token_source: "agent_scoped_env_var:AGENT_BEARER_TOKEN"
}
8 changes: 8 additions & 0 deletions samples.json
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,14 @@
"min_cli_version": "0.28.0",
"kind": "solution"
},
{
"slug": "internal-caller-agent",
"name": "Internal Caller Agent",
"tagline": "Shows how an agent can call an authenticated API with an agent-scoped bearer token.",
"current_version": "v0.1.0",
"min_cli_version": "0.28.0",
"kind": "agent"
},
{
"slug": "onboarding-qa",
"name": "Onboarding Q&A",
Expand Down
Loading