Files
AOS/agency-agents/skills/license-lifecycle/SKILL.md
T
Z User 136379c666 feat: zeroclaw agentic agency architecture — agents, skills, Rust crates
- 18 agent specs across Software, Support, Marketing, Cross-cutting
  (orchestrator + 7 software + 5 support + 3 cross-cutting + leads-finder)
- 8 reusable skills (handoff, pr-review, dokploy-deploy, campaign-structure,
  content-calendar, ticket-triage, license-lifecycle, invoice-draft)
- 3 JSON schemas: handoff, deliverable, approval
- Policies: autonomy levels, tool risk classification, compliance (DSGVO/GoBD/UWG)
- routing.toml: model tiers T1/T2/T3 + provider config (PII gating)
- Rust workspace (5 crates, all compile + 16 tests pass):
  - aos-mcp: tool registry + risk tagging
  - aos-policy: autonomy levels, budget enforcement, approval requests
  - aos-license: ed25519 license issue/verify (real crypto + CLI binary)
  - aos-ledger: integer-cents money math, gapless numbering, VAT, audit chain
  - aos-sync: frontmatter validator (18/18 specs pass), CLI binary
- CLAUDE.md entry point with architecture overview + roadmap
2026-10-30 13:01:03 +00:00

4.8 KiB

name, version, applies_to, risk
name version applies_to risk
license-lifecycle 1.0.0
license-lead
license-ops-agent
high

License Lifecycle

When to use

When a task requires issuing, renewing, extending, or revoking a software license key for a client. Issuing is high-risk because keys are cryptographically signed and bound to client identity; revoking is always human-approved.

Steps

  1. Read the task: client record, product/SKU, license type (subscription / perpetual / trial), binding (domain / instance id / seat count), and requested expiry.
  2. Confirm the client's entitlement in AOS: signed contract / order covering this SKU and quantity. No entitlement → blocked.
  3. Issue via the aos-license Rust crate only. The crate generates an Ed25519-signed key bound to the requested domain/instance and records (key id, client id, product, binding, issued_at, expires_at, signing key id). Never invent or format a key string in the prompt — any key produced outside the crate is invalid and a security incident.
  4. Bind the key to the domain / instance / seat count as recorded by the crate. Rebinding requires a revoke + reissue, not an in-place edit.
  5. Set expiry per the contract. For subscriptions, schedule renewal reminders (30 / 7 / 1 days before expiry) via AOS scheduled tasks. For trials, set the trial expiry and a single reminder.
  6. Write the license record to AOS via the crate's commit call (the crate owns the write). Record the key id (not the key itself) in the AOS note — the key is delivered through a documented secure channel, never pasted in a ticket or commit.
  7. Deliver the key to the client via a handoff to accounting-lead or support-lead (a welcome email → send_client_communication approval). The agent never calls a send tool; first client delivery is always human-approved.
  8. For renewal / extension: re-run step 3 with the existing license id, updated expiry, and a fresh signature. Old expiry is retained in the audit log (GoBD — no deletion of prior state).
  9. For revocation: do not revoke directly. Compose an ApprovalRequest (schemas/approval.json): action: revoke_license, risk: high, rationale (cancellation / abuse / chargeback / security incident), diff_summary (license id, client id, product, binding, reason), payload: { license_id, client_id, reason, effective_at }.
  10. On approval, the policy crate calls aos:revoke_license. The crate marks the license revoked with timestamp + reason and retains the record (GoBD — revoked licenses are retained, never deleted).
  11. Write a note on the task: action taken, license id, binding, expiry, approver (for revocation), AOS record ref.

Inputs

  • A task with task_id, client id, product/SKU, license type, binding, and expiry.
  • The client's entitlement record in AOS (contract / order).
  • For revocation: a documented reason (cancellation / abuse / chargeback / security incident).

Outputs

An AgentDeliverable (schemas/deliverable.json) with:

  • status: done (issued / renewed) | needs_approval (revoke pending) | blocked (no entitlement / missing binding / invalid request)
  • deliverables[]: the AOS license record ref (aos_record), the key id (not the key), the scheduled reminder task refs.
  • risks[]: trial-to-paid assumptions, binding ambiguity, expiry-vs-contract mismatch, entitlement inferred.
  • cost: tokens only (no external spend; the crate does the signing).

Guard rails / compliance

  • Keys are generated only by the aos-license Rust crate. Any key string produced by an LLM in the prompt is invalid and treated as a security incident — do not paste, format, or "example" a key.
  • Revocation is always human-approved via an ApprovalRequest of action revoke_license. No auto-revoke, no auto-expire-shortening.
  • GoBD: revoked and expired licenses are retained, never deleted; history (issuance, renewal, revocation) is append-only in the audit log.
  • DSGVO: license keys are credentials. Do not paste them into tickets, commits, chat, or LLM prompts. Deliver only through documented secure channels; first client delivery is human-approved.
  • Binding integrity: changing the binding (domain/instance/seat) is a revoke + reissue, never an in-place edit. Expiry must match the contract — shorter is a client-rights violation → blocked.
  • Reissuing a lost key requires verifying the requester is the contract holder — never reissue on an unverified support request.

References

  • schemas/approval.json — revoke_license action
  • schemas/deliverable.json — return envelope
  • policies/compliance.md — GoBD retention, DSGVO, secrets
  • policies/tool-risk.md — aos:revoke_license is risk: high
  • crates/aos-license — Ed25519 signing, gapless license id, audit log