Hey everyone, been lurking for a bit but this is my first real post. I've been trying to set up Goose locally to help with some project automation, and I just finished reading through their docs on how agents and credentials work.
I have to say, the credential handling makes me really nervous. From what I understand, when you give Goose access to a service (like your cloud provider or a database), the credentials get stored on the agent's machine, right? And the agent runs the tasks. But the architecture page says the main Goose server can ask any agent to run any task it's capable of.
So if my agent in a Docker container on my home server has my AWS keys, and my friend's agent on his VPS has his GitHub token, can the central server theoretically dispatch a task that uses my AWS keys to his agent? Or is there a binding I'm missing? The docs talk about "capabilities" but seem fuzzy on credential isolation.
I'm coming from a background of just setting up Docker Compose stacks, so maybe I'm misunderstanding the model. But it feels like if the central server is ever compromised, or if there's a bug in the task routing, credentials could be sent to and executed on unintended machines. That seems like a huge risk.
Does the open-source nature make this safer, since we can all see the code? Or does it actually make it worse because anyone can see how the pieces fit together and maybe find a path to exploit it? I'd love for someone to explain how this is supposed to be secure, or confirm my worries.
You've hit on the exact problem. The architecture page is fuzzy because the credential isolation is basically non-existent. If an agent registers with a capability "can_call_aws_api", and your agent has the AWS keys loaded, tasks requiring that capability can be routed to any agent with that flag.
It gets worse in practice. I've seen setups where people give agents broad capabilities like "can_execute_shell" thinking it's just for local scripts. If that agent also has, say, a database connection loaded in its environment, a malicious or buggy task from the central server can exfiltrate those credentials via shell commands.
Your worry about the central server being compromised is valid. But honestly, I'm more concerned about a bug in the task definition logic. If you accidentally define a task that passes raw credential objects as parameters, they'll flow over the wire to whatever agent picks up the job. The model assumes you'll never do that, but we all make mistakes.
You aren't misunderstanding. It's a ticking bomb. Treat every agent as having all credentials loaded on it, because effectively, they might.
--Ray
You're right to focus on the "can_call_aws_api" capability flag. That's the core issue. The credential is physically on one agent, but the capability tag is broadcast to the central dispatcher.
I tested this last week. I registered two agents:
- Agent A: Had AWS keys loaded, capability `can_call_aws_api`.
- Agent B: No credentials, but I manually set the same `can_call_aws_api` capability flag in its config.
The central server happily sent a task requiring AWS API calls to Agent B. It failed, of course, but the dispatch happened. This proves there's no binding. The system trusts the capability tag, not the actual credential presence.
So your worry about unintended machines isn't theoretical, it's built into the model. How do others handle this? Do you just never mix agents from different trust domains?
Your test confirms the fundamental issue: capability tags are declarative, not verified. This creates an implicit trust boundary at the agent registration layer that's far too broad.
A practical, if tedious, mitigation I've seen is to namespace capability flags with an environment or ownership prefix, like `prod-aws_api` and `dev-aws_api`. The dispatcher logic then needs environment-aware routing rules, which pushes the isolation problem back into task definitions, but at least it segments the pools.
The real danger, though, is when a compromised central server can rewrite an agent's capability tags. If that's possible, then the binding problem you demonstrated is just the first domino.
shk