Sign in

Agent IO

@agent.io
28 followers 26 following 98 posts

Fetching and serving by @babu.dev. Application superpowers on the Envoy proxy.

PostsRepliesMedia
Agent IO @agent.io · 05/05/2026
Recently I added support for proxying "raw" TCP ports so that IO could proxy SSH and other non-HTTP services. Here's an updated start screen that describes all of IO's modes.
000
Agent IO @agent.io · 28/01/2026
Among many other things, you can use it to send Bluesky chat messages.
# izakaya:~/Desktop/agentio/slink
$ CONVOID=$(SLINK_ATPROTOPROXY=did:web:api.bsky.chat#bsky_chat slink call chat.bsky.convo get-convo-for-members --members $(slink resolve did timburks.me) --members $(slink resolve did agent.io) | jq .convo.id -r)
# izakaya:~/Desktop/agentio/slink
$ echo $CONVOID
3md2h2kakjk22
# izakaya:~/Desktop/agentio/slink
$ vi message.json
# izakaya:~/Desktop/agentio/slink
$ cat message.json
{"text":"Here's your CLI-generated Bluesky chat message! I built a mechanically-generated CLI that calls XRPC functions. I'm using it to send you this with chat.bsky.convo.sendMessage"}
# izakaya:~/Desktop/agentio/slink
$ SLINK_ATPROTOPROXY=did:web:api.bsky.chat#bsky_chat slink call chat.bsky.convo send-message --convo-id $CONVOID --message message.json
{
  "id": "3mdjbt5flrc26",
  "rev": "2222224a7rehk",
  "sender": {
    "did": "did:plc:ahr5yhciwadehhwm7fotyfju"
  },
  "sentAt": "2026-01-28T22:06:03.745Z",
  "text": "Here's your CLI-generated Bluesky chat message! I built a mechanically-generated CLI that calls XRPC functions. I'm using it to send you this with chat.bsky.convo.sendMessage"
}A chat view showing the message that I just sent.
100
Agent IO @agent.io · 09/01/2026
Another thing that auth scopes don't provide is visibility into how auth tokens are used. So IO allows traffic histories to be exported as HAR files that show us all the approved and blocked requests.
$ ssh localhost -p 2200 -- get traffic -m calling -a digitaloceandns -l 1
{
  "log": {
    "version": "1.2",
    "creator": {
      "name": "IO",
      "version": "v0.1.75-f45f06b2*"
    },
    "entries": [
      {
        "startedDateTime": "2026-01-09T14:53:54-08:00",
        "time": 0,
        "request": {
          "method": "DELETE",
          "url": "/v2/domains/agent.io/records/1781875673",
          "headers": [
            {
              "name": ":authority",
              "value": "localhost:5000"
            },
            {
              "name": ":path",
              "value": "/v2/domains/agent.io/records/1781875673"
            },
            {
              "name": ":method",
              "value": "DELETE"
            },
            {
              "name": ":scheme",
              "value": "http"
            },
            {
              "name": "user-agent",
              "value": "curl/8.12.1"
            },
            {
              "name": "accept",
              "value": "*/*"
            },
            {
              "name": "x-forwarded-for",
              "value": "192.168.4.172"
            },
            {
              "name": "x-forwarded-proto",
              "value": "http"
            },Here we see that the disallowed request was blocked by IO, which returned a 403 (Forbidden) error
000
Agent IO @agent.io · 09/01/2026
Auth scopes are great but they don't always restrict access as much as we want. Here's an IO configuration that *only* allows a couple of authorized API key users to call a few named methods of the Digital Ocean DNS API using a token that it gets from Hashicorp Vault.
calling "digitaloceandns" {
  name   = "Digital Ocean DNS"
  target = "api.digitalocean.com"
  port   = 5000
  require_apikey {
    users = <<END
fury:{SHA}czqgP91Ev45QGKCokt/+mBIHgn8=
hulk:{SHA}Mf6CeupM9fas594sId4LX2t4OFg=
END
  }
  apply_header "authorization" {
    secret = "vault:default/io/digitalocean-dns"
  }
  operation "retrieve-domain" {
    method = "GET"
    path = "/v2/domains/{domain}"
  }
  operation "retrieve-domain-records" {
    method = "GET"
    path = "/v2/domains/{domain}/records"
  }
  operation "retrieve-domain-record" {
    method = "GET"
    path = "/v2/domains/{domain}/records/{recordid}"
  }
}
110
Agent IO @agent.io · 06/01/2026
Here's IO running on MacOS agent.io/decisions/ma...
011
Agent IO @agent.io · 01/08/2025
Here's a practical benefit of our exploration of @hashicorp.com's Nomad and Vault: all of the configuration for this Nomad-hosted ATProto PDS is now read from secrets in Vault.
Here we are in the Nomad console looking at the configuration for our PDS. The job description contains a template that puts secrets from Vault into our job's environment.The Vault console shows the secret that contains our PDS configuration. Here is the index page for our running PDS!
010
Agent IO @agent.io · 29/07/2025
Here's IO using an API key that it read from Vault using its Nomad workload identity.
The IO console showing the configuration of the Wordnik API above a curl call to the API.The Vault entry for the Wordnik secret.The Nomad configuration for IO showing its workload identity configuration.
020
Agent IO @agent.io · 06/07/2025
Experimenting with Open Telemetry: here's a Grafana dashboard showing requests per host in a small fleet of IOs
010