feat(agentstack): add delegation authority checks (#87)

This commit is contained in:
Qyra-One 2026-07-01 04:14:40 -04:00 • committed by GitHub
parent c495041adb
commit 0bca203527
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 92 additions and 27 deletions

View file

@ -120,15 +120,38 @@ describe("AgentStack coordinator", () => {
it("records delegation grants and emits events", () => {
const stack = new AgentStack();
const listener = vi.fn();
stack.on(listener);
stack.registerAgent(agent);
const grant = stack.delegate(owner, agent.did, ["tasks:create"]);
expect(grant.ownerDid).toBe(owner);
expect(grant.agentDid).toBe(agent.did);
expect(listener).toHaveBeenCalledWith(expect.objectContaining({ type: "agent.registered" }));
expect(listener).toHaveBeenCalledWith(expect.objectContaining({ type: "delegation.granted" }));
});
stack.on(listener);
stack.registerAgent(agent);
const grant = stack.delegate(owner, agent.did, ["tasks:create"]);
expect(grant.ownerDid).toBe(owner);
expect(grant.agentDid).toBe(agent.did);
expect(listener).toHaveBeenCalledWith(expect.objectContaining({ type: "agent.registered" }));
expect(listener).toHaveBeenCalledWith(expect.objectContaining({ type: "delegation.granted" }));
});
it("checks active delegation authority by owner, agent, scope, and expiry", () => {
const stack = new AgentStack(() => "2026-01-01T00:00:00.000Z");
stack.registerAgent(agent);
stack.delegate(owner, agent.did, ["tasks:create"], "2026-01-02T00:00:00.000Z");
expect(stack.hasDelegation(owner, agent.did, "tasks:create")).toBe(true);
expect(stack.hasDelegation(owner, agent.did, "tasks:update")).toBe(false);
expect(stack.hasDelegation(owner, agent.did, "tasks:create", "2026-01-03T00:00:00.000Z")).toBe(false);
expect(stack.listDelegations({ ownerDid: owner, agentDid: agent.did, scope: "tasks:create" })).toHaveLength(1);
expect(stack.listDelegations({ activeAt: "2026-01-03T00:00:00.000Z" })).toHaveLength(0);
});
it("allows wildcard delegation scopes and ignores revoked grants", () => {
const stack = new AgentStack();
stack.registerAgent(agent);
const grant = stack.delegate(owner, agent.did, ["*"]);
expect(stack.hasDelegation(owner, agent.did, "tasks:update")).toBe(true);
stack.revokeDelegation(grant.id);
expect(stack.hasDelegation(owner, agent.did, "tasks:update")).toBe(false);
});
it("rejects unknown agents and invalid DIDs", () => {
const stack = new AgentStack();