aegis-devops 0.3.2__tar.gz → 1.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (158) hide show
  1. {aegis_devops-0.3.2/src/aegis_devops.egg-info → aegis_devops-1.1.0}/PKG-INFO +84 -19
  2. {aegis_devops-0.3.2 → aegis_devops-1.1.0}/README.md +82 -17
  3. {aegis_devops-0.3.2 → aegis_devops-1.1.0}/pyproject.toml +2 -2
  4. {aegis_devops-0.3.2 → aegis_devops-1.1.0}/src/aegis_core/__init__.py +1 -1
  5. aegis_devops-1.1.0/src/aegis_core/_examples/__pycache__/__init__.cpython-312.pyc +0 -0
  6. {aegis_devops-0.3.2 → aegis_devops-1.1.0}/src/aegis_core/_examples/agents.example.yaml +3 -0
  7. aegis_devops-1.1.0/src/aegis_core/_examples/agents.example.yaml.sig +2 -0
  8. {aegis_devops-0.3.2 → aegis_devops-1.1.0}/src/aegis_core/_examples/authority.example.yaml +1 -0
  9. aegis_devops-1.1.0/src/aegis_core/_examples/authority.example.yaml.sig +2 -0
  10. aegis_devops-1.1.0/src/aegis_core/_examples/budget.example.yaml +21 -0
  11. aegis_devops-1.1.0/src/aegis_core/_examples/budget.example.yaml.sig +2 -0
  12. aegis_devops-1.1.0/src/aegis_core/budget/__init__.py +27 -0
  13. aegis_devops-1.1.0/src/aegis_core/budget/accounting.py +693 -0
  14. aegis_devops-1.1.0/src/aegis_core/budget/evaluate.py +259 -0
  15. aegis_devops-1.1.0/src/aegis_core/budget/gate.py +124 -0
  16. aegis_devops-1.1.0/src/aegis_core/budget/logs.py +678 -0
  17. aegis_devops-1.1.0/src/aegis_core/budget/policy.py +235 -0
  18. aegis_devops-1.1.0/src/aegis_core/budget/prices.json +282 -0
  19. aegis_devops-1.1.0/src/aegis_core/budget/prices.yaml +77 -0
  20. aegis_devops-1.1.0/src/aegis_core/budget/pricing.py +186 -0
  21. aegis_devops-1.1.0/src/aegis_core/budget/report.py +205 -0
  22. {aegis_devops-0.3.2 → aegis_devops-1.1.0}/src/aegis_core/cli.py +307 -2
  23. {aegis_devops-0.3.2 → aegis_devops-1.1.0}/src/aegis_core/environments.py +98 -28
  24. {aegis_devops-0.3.2 → aegis_devops-1.1.0}/src/aegis_core/hook.py +248 -44
  25. {aegis_devops-0.3.2 → aegis_devops-1.1.0}/src/aegis_core/identity.py +17 -3
  26. {aegis_devops-0.3.2 → aegis_devops-1.1.0}/src/aegis_core/integrations/opencode-plugin.js +51 -12
  27. {aegis_devops-0.3.2 → aegis_devops-1.1.0}/src/aegis_core/interceptor.py +53 -6
  28. {aegis_devops-0.3.2 → aegis_devops-1.1.0}/src/aegis_core/parser.py +11 -3
  29. aegis_devops-1.1.0/src/aegis_core/report_aws.py +481 -0
  30. aegis_devops-1.1.0/src/aegis_core/report_kubernetes.py +354 -0
  31. {aegis_devops-0.3.2 → aegis_devops-1.1.0}/src/aegis_core/shell.py +179 -3
  32. {aegis_devops-0.3.2 → aegis_devops-1.1.0}/src/aegis_core/store.py +99 -0
  33. {aegis_devops-0.3.2 → aegis_devops-1.1.0/src/aegis_devops.egg-info}/PKG-INFO +84 -19
  34. {aegis_devops-0.3.2 → aegis_devops-1.1.0}/src/aegis_devops.egg-info/SOURCES.txt +23 -0
  35. {aegis_devops-0.3.2 → aegis_devops-1.1.0}/tests/test_adversarial.py +14 -12
  36. {aegis_devops-0.3.2 → aegis_devops-1.1.0}/tests/test_authority.py +2 -2
  37. aegis_devops-1.1.0/tests/test_budget_accounting.py +492 -0
  38. aegis_devops-1.1.0/tests/test_budget_cli.py +247 -0
  39. aegis_devops-1.1.0/tests/test_budget_evaluate.py +130 -0
  40. aegis_devops-1.1.0/tests/test_budget_hook.py +274 -0
  41. aegis_devops-1.1.0/tests/test_budget_logs.py +365 -0
  42. aegis_devops-1.1.0/tests/test_budget_policy.py +304 -0
  43. {aegis_devops-0.3.2 → aegis_devops-1.1.0}/tests/test_docs_consistency.py +31 -0
  44. {aegis_devops-0.3.2 → aegis_devops-1.1.0}/tests/test_environments.py +47 -1
  45. {aegis_devops-0.3.2 → aegis_devops-1.1.0}/tests/test_hook.py +74 -0
  46. {aegis_devops-0.3.2 → aegis_devops-1.1.0}/tests/test_identity.py +36 -0
  47. aegis_devops-1.1.0/tests/test_kubectl_namespace_and_manifests.py +222 -0
  48. {aegis_devops-0.3.2 → aegis_devops-1.1.0}/tests/test_opencode_plugin.py +37 -0
  49. {aegis_devops-0.3.2 → aegis_devops-1.1.0}/tests/test_parser.py +7 -5
  50. aegis_devops-1.1.0/tests/test_plugins.py +253 -0
  51. aegis_devops-1.1.0/tests/test_report_aws.py +349 -0
  52. aegis_devops-1.1.0/tests/test_report_kubernetes.py +247 -0
  53. {aegis_devops-0.3.2 → aegis_devops-1.1.0}/tests/test_shell.py +64 -0
  54. {aegis_devops-0.3.2 → aegis_devops-1.1.0}/tests/test_signing.py +2 -1
  55. aegis_devops-0.3.2/src/aegis_core/_examples/__pycache__/__init__.cpython-312.pyc +0 -0
  56. aegis_devops-0.3.2/src/aegis_core/_examples/agents.example.yaml.sig +0 -2
  57. aegis_devops-0.3.2/src/aegis_core/_examples/authority.example.yaml.sig +0 -2
  58. aegis_devops-0.3.2/tests/test_plugins.py +0 -112
  59. {aegis_devops-0.3.2 → aegis_devops-1.1.0}/LICENSE +0 -0
  60. {aegis_devops-0.3.2 → aegis_devops-1.1.0}/MANIFEST.in +0 -0
  61. {aegis_devops-0.3.2 → aegis_devops-1.1.0}/setup.cfg +0 -0
  62. {aegis_devops-0.3.2 → aegis_devops-1.1.0}/src/aegis_core/_examples/__init__.py +0 -0
  63. {aegis_devops-0.3.2 → aegis_devops-1.1.0}/src/aegis_core/_examples/constraints.example.yaml +0 -0
  64. {aegis_devops-0.3.2 → aegis_devops-1.1.0}/src/aegis_core/_examples/constraints.example.yaml.sig +0 -0
  65. {aegis_devops-0.3.2 → aegis_devops-1.1.0}/src/aegis_core/_examples/environments.example.yaml +0 -0
  66. {aegis_devops-0.3.2 → aegis_devops-1.1.0}/src/aegis_core/_examples/environments.example.yaml.sig +0 -0
  67. {aegis_devops-0.3.2 → aegis_devops-1.1.0}/src/aegis_core/_examples/example-signing.key +0 -0
  68. {aegis_devops-0.3.2 → aegis_devops-1.1.0}/src/aegis_core/_examples/plan_constraints.example.yaml +0 -0
  69. {aegis_devops-0.3.2 → aegis_devops-1.1.0}/src/aegis_core/_examples/plan_constraints.example.yaml.sig +0 -0
  70. {aegis_devops-0.3.2 → aegis_devops-1.1.0}/src/aegis_core/_examples/repos.example.yaml +0 -0
  71. {aegis_devops-0.3.2 → aegis_devops-1.1.0}/src/aegis_core/_examples/repos.example.yaml.sig +0 -0
  72. {aegis_devops-0.3.2 → aegis_devops-1.1.0}/src/aegis_core/_examples/signers.example.yaml +0 -0
  73. {aegis_devops-0.3.2 → aegis_devops-1.1.0}/src/aegis_core/_examples/signers.example.yaml.sig +0 -0
  74. {aegis_devops-0.3.2 → aegis_devops-1.1.0}/src/aegis_core/_examples/sources/AEGIS-MANIFEST.sig +0 -0
  75. {aegis_devops-0.3.2 → aegis_devops-1.1.0}/src/aegis_core/_examples/sources/PRINCIPALS.yaml +0 -0
  76. {aegis_devops-0.3.2 → aegis_devops-1.1.0}/src/aegis_core/_examples/sources/git-4001.json +0 -0
  77. {aegis_devops-0.3.2 → aegis_devops-1.1.0}/src/aegis_core/_examples/sources/git-6001.json +0 -0
  78. {aegis_devops-0.3.2 → aegis_devops-1.1.0}/src/aegis_core/_examples/sources/git-6002.json +0 -0
  79. {aegis_devops-0.3.2 → aegis_devops-1.1.0}/src/aegis_core/_examples/sources/git-6003.json +0 -0
  80. {aegis_devops-0.3.2 → aegis_devops-1.1.0}/src/aegis_core/_examples/sources/git-6004.json +0 -0
  81. {aegis_devops-0.3.2 → aegis_devops-1.1.0}/src/aegis_core/_examples/sources/git-6005.json +0 -0
  82. {aegis_devops-0.3.2 → aegis_devops-1.1.0}/src/aegis_core/_examples/sources/git-6006.json +0 -0
  83. {aegis_devops-0.3.2 → aegis_devops-1.1.0}/src/aegis_core/_examples/sources/git-6007.json +0 -0
  84. {aegis_devops-0.3.2 → aegis_devops-1.1.0}/src/aegis_core/_examples/sources/git-6008.json +0 -0
  85. {aegis_devops-0.3.2 → aegis_devops-1.1.0}/src/aegis_core/_examples/sources/git-6009.json +0 -0
  86. {aegis_devops-0.3.2 → aegis_devops-1.1.0}/src/aegis_core/_examples/sources/git-789abc.json +0 -0
  87. {aegis_devops-0.3.2 → aegis_devops-1.1.0}/src/aegis_core/_examples/sources/git-abc123.json +0 -0
  88. {aegis_devops-0.3.2 → aegis_devops-1.1.0}/src/aegis_core/_examples/sources/git-bcd234.json +0 -0
  89. {aegis_devops-0.3.2 → aegis_devops-1.1.0}/src/aegis_core/_examples/sources/git-def456.json +0 -0
  90. {aegis_devops-0.3.2 → aegis_devops-1.1.0}/src/aegis_core/_examples/sources/jira-1001.json +0 -0
  91. {aegis_devops-0.3.2 → aegis_devops-1.1.0}/src/aegis_core/_examples/sources/jira-1002.json +0 -0
  92. {aegis_devops-0.3.2 → aegis_devops-1.1.0}/src/aegis_core/_examples/sources/jira-2001.json +0 -0
  93. {aegis_devops-0.3.2 → aegis_devops-1.1.0}/src/aegis_core/_examples/sources/jira-2002.json +0 -0
  94. {aegis_devops-0.3.2 → aegis_devops-1.1.0}/src/aegis_core/_examples/sources/jira-3001.json +0 -0
  95. {aegis_devops-0.3.2 → aegis_devops-1.1.0}/src/aegis_core/_examples/sources/jira-3002.json +0 -0
  96. {aegis_devops-0.3.2 → aegis_devops-1.1.0}/src/aegis_core/_examples/sources/jira-3003.json +0 -0
  97. {aegis_devops-0.3.2 → aegis_devops-1.1.0}/src/aegis_core/_examples/sources/jira-3004.json +0 -0
  98. {aegis_devops-0.3.2 → aegis_devops-1.1.0}/src/aegis_core/_examples/sources/jira-3005.json +0 -0
  99. {aegis_devops-0.3.2 → aegis_devops-1.1.0}/src/aegis_core/_examples/sources/jira-5001.json +0 -0
  100. {aegis_devops-0.3.2 → aegis_devops-1.1.0}/src/aegis_core/_examples/sources/jira-5002.json +0 -0
  101. {aegis_devops-0.3.2 → aegis_devops-1.1.0}/src/aegis_core/_examples/sources/jira-5003.json +0 -0
  102. {aegis_devops-0.3.2 → aegis_devops-1.1.0}/src/aegis_core/_examples/sources/jira-5004.json +0 -0
  103. {aegis_devops-0.3.2 → aegis_devops-1.1.0}/src/aegis_core/_examples/sources/jira-5006.json +0 -0
  104. {aegis_devops-0.3.2 → aegis_devops-1.1.0}/src/aegis_core/_examples/sources/plan-1001.json +0 -0
  105. {aegis_devops-0.3.2 → aegis_devops-1.1.0}/src/aegis_core/_examples/sources/plan-1002.json +0 -0
  106. {aegis_devops-0.3.2 → aegis_devops-1.1.0}/src/aegis_core/_examples/sources/plan-1003.json +0 -0
  107. {aegis_devops-0.3.2 → aegis_devops-1.1.0}/src/aegis_core/_examples/sources/plan-1004.json +0 -0
  108. {aegis_devops-0.3.2 → aegis_devops-1.1.0}/src/aegis_core/_examples/sources/plan-5005.json +0 -0
  109. {aegis_devops-0.3.2 → aegis_devops-1.1.0}/src/aegis_core/_examples/sources/slack-perma-1.json +0 -0
  110. {aegis_devops-0.3.2 → aegis_devops-1.1.0}/src/aegis_core/adversarial.py +0 -0
  111. {aegis_devops-0.3.2 → aegis_devops-1.1.0}/src/aegis_core/audit_aws.py +0 -0
  112. {aegis_devops-0.3.2 → aegis_devops-1.1.0}/src/aegis_core/audit_kubernetes.py +0 -0
  113. {aegis_devops-0.3.2 → aegis_devops-1.1.0}/src/aegis_core/authority.py +0 -0
  114. {aegis_devops-0.3.2 → aegis_devops-1.1.0}/src/aegis_core/baselines/__init__.py +0 -0
  115. {aegis_devops-0.3.2 → aegis_devops-1.1.0}/src/aegis_core/baselines/base.py +0 -0
  116. {aegis_devops-0.3.2 → aegis_devops-1.1.0}/src/aegis_core/baselines/external.py +0 -0
  117. {aegis_devops-0.3.2 → aegis_devops-1.1.0}/src/aegis_core/baselines/llm.py +0 -0
  118. {aegis_devops-0.3.2 → aegis_devops-1.1.0}/src/aegis_core/baselines/metrics.py +0 -0
  119. {aegis_devops-0.3.2 → aegis_devops-1.1.0}/src/aegis_core/baselines/opa.py +0 -0
  120. {aegis_devops-0.3.2 → aegis_devops-1.1.0}/src/aegis_core/compile/__init__.py +0 -0
  121. {aegis_devops-0.3.2 → aegis_devops-1.1.0}/src/aegis_core/compile/actions/aws.yaml +0 -0
  122. {aegis_devops-0.3.2 → aegis_devops-1.1.0}/src/aegis_core/compile/aws.py +0 -0
  123. {aegis_devops-0.3.2 → aegis_devops-1.1.0}/src/aegis_core/compile/kubernetes.py +0 -0
  124. {aegis_devops-0.3.2 → aegis_devops-1.1.0}/src/aegis_core/config.py +0 -0
  125. {aegis_devops-0.3.2 → aegis_devops-1.1.0}/src/aegis_core/gitsource.py +0 -0
  126. {aegis_devops-0.3.2 → aegis_devops-1.1.0}/src/aegis_core/intent.py +0 -0
  127. {aegis_devops-0.3.2 → aegis_devops-1.1.0}/src/aegis_core/ledger.py +0 -0
  128. {aegis_devops-0.3.2 → aegis_devops-1.1.0}/src/aegis_core/parsers/__init__.py +0 -0
  129. {aegis_devops-0.3.2 → aegis_devops-1.1.0}/src/aegis_core/parsers/pulumi.py +0 -0
  130. {aegis_devops-0.3.2 → aegis_devops-1.1.0}/src/aegis_core/parsers/sql.py +0 -0
  131. {aegis_devops-0.3.2 → aegis_devops-1.1.0}/src/aegis_core/plan.py +0 -0
  132. {aegis_devops-0.3.2 → aegis_devops-1.1.0}/src/aegis_core/provenance.py +0 -0
  133. {aegis_devops-0.3.2 → aegis_devops-1.1.0}/src/aegis_core/signing.py +0 -0
  134. {aegis_devops-0.3.2 → aegis_devops-1.1.0}/src/aegis_devops.egg-info/dependency_links.txt +0 -0
  135. {aegis_devops-0.3.2 → aegis_devops-1.1.0}/src/aegis_devops.egg-info/entry_points.txt +0 -0
  136. {aegis_devops-0.3.2 → aegis_devops-1.1.0}/src/aegis_devops.egg-info/requires.txt +0 -0
  137. {aegis_devops-0.3.2 → aegis_devops-1.1.0}/src/aegis_devops.egg-info/top_level.txt +0 -0
  138. {aegis_devops-0.3.2 → aegis_devops-1.1.0}/tests/test_audit_aws.py +0 -0
  139. {aegis_devops-0.3.2 → aegis_devops-1.1.0}/tests/test_audit_kubernetes.py +0 -0
  140. {aegis_devops-0.3.2 → aegis_devops-1.1.0}/tests/test_baselines.py +0 -0
  141. {aegis_devops-0.3.2 → aegis_devops-1.1.0}/tests/test_benchmark.py +0 -0
  142. {aegis_devops-0.3.2 → aegis_devops-1.1.0}/tests/test_cli.py +0 -0
  143. {aegis_devops-0.3.2 → aegis_devops-1.1.0}/tests/test_compile_aws.py +0 -0
  144. {aegis_devops-0.3.2 → aegis_devops-1.1.0}/tests/test_compile_kubernetes.py +0 -0
  145. {aegis_devops-0.3.2 → aegis_devops-1.1.0}/tests/test_config.py +0 -0
  146. {aegis_devops-0.3.2 → aegis_devops-1.1.0}/tests/test_corpus.py +0 -0
  147. {aegis_devops-0.3.2 → aegis_devops-1.1.0}/tests/test_default_rules.py +0 -0
  148. {aegis_devops-0.3.2 → aegis_devops-1.1.0}/tests/test_gitsource.py +0 -0
  149. {aegis_devops-0.3.2 → aegis_devops-1.1.0}/tests/test_intent.py +0 -0
  150. {aegis_devops-0.3.2 → aegis_devops-1.1.0}/tests/test_interceptor.py +0 -0
  151. {aegis_devops-0.3.2 → aegis_devops-1.1.0}/tests/test_ledger.py +0 -0
  152. {aegis_devops-0.3.2 → aegis_devops-1.1.0}/tests/test_parsers_pulumi.py +0 -0
  153. {aegis_devops-0.3.2 → aegis_devops-1.1.0}/tests/test_parsers_sql.py +0 -0
  154. {aegis_devops-0.3.2 → aegis_devops-1.1.0}/tests/test_plan.py +0 -0
  155. {aegis_devops-0.3.2 → aegis_devops-1.1.0}/tests/test_provenance.py +0 -0
  156. {aegis_devops-0.3.2 → aegis_devops-1.1.0}/tests/test_snapshot.py +0 -0
  157. {aegis_devops-0.3.2 → aegis_devops-1.1.0}/tests/test_store.py +0 -0
  158. {aegis_devops-0.3.2 → aegis_devops-1.1.0}/tests/test_store_match.py +0 -0
@@ -1,13 +1,13 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: aegis-devops
3
- Version: 0.3.2
3
+ Version: 1.1.0
4
4
  Summary: Provenance-backed, authority-aware policy verifier for agentic DevOps actions.
5
5
  Author: Vamshidher Reddy Jannapu Reddy
6
6
  License-Expression: Apache-2.0
7
7
  Project-URL: Homepage, https://github.com/moneytool/aegis-devops
8
8
  Project-URL: Repository, https://github.com/moneytool/aegis-devops
9
9
  Keywords: agentops,agent-security,policy-as-code,provenance,kubernetes,terraform,guardrails,prompt-injection,context-poisoning
10
- Classifier: Development Status :: 3 - Alpha
10
+ Classifier: Development Status :: 4 - Beta
11
11
  Classifier: Environment :: Console
12
12
  Classifier: Intended Audience :: System Administrators
13
13
  Classifier: Intended Audience :: Developers
@@ -46,30 +46,43 @@ become policy.
46
46
 
47
47
  ![Aegis-DevOps blocking an injected kubectl delete](docs/where-it-sits.gif)
48
48
 
49
- ### Install in Claude Code
49
+ ## Try it in 60 seconds
50
+
51
+ **1. Watch it block a pull request (nothing to install).** Open the demo's
52
+ [example PR](https://github.com/moneytool/aegis-devops-demo/pull/1): it deletes a production
53
+ database, and the failing check is Aegis blocking it, with the verdict posted as a comment. Fork
54
+ the [demo repository](https://github.com/moneytool/aegis-devops-demo) to try your own change; no
55
+ cloud account needed.
56
+
57
+ **2. Check a command yourself:**
50
58
 
51
59
  ```bash
52
60
  pip install aegis-devops && aegis init .aegis
53
- claude plugin marketplace add moneytool/aegis-devops
54
- claude plugin install aegis-devops@aegis-devops
61
+ aegis check command --pretty -- "kubectl delete namespace prod" # BLOCK (exit 3)
62
+ aegis check command --pretty -- "kubectl get pods -n prod" # ALLOW (exit 0)
55
63
  ```
56
64
 
57
- ### Install in Gemini CLI
65
+ **3. Put it in front of your coding agent.** In the same project:
58
66
 
59
67
  ```bash
60
- pip install aegis-devops && aegis init .aegis
61
- gemini extensions install https://github.com/moneytool/aegis-devops
68
+ claude plugin marketplace add moneytool/aegis-devops
69
+ claude plugin install aegis-devops@aegis-devops
62
70
  ```
63
71
 
64
- Codex, GitHub Copilot (CLI and VS Code), Cursor and OpenCode:
65
- `aegis install codex|copilot|vscode|cursor|opencode`
66
- (see [Coding agents](docs/agents.md)). It only acts in projects with a `.aegis/` policy, and
67
- only blocks what that policy blocks. It also works as a CI step
68
- (`aegis check terraform plan.json --exit-style ci`) and as a Python library; see
69
- [Quick start](#quick-start). In GitHub Actions, the
70
- [Aegis-DevOps Plan Check](https://github.com/marketplace/actions/aegis-devops-plan-check) Action
71
- checks a Terraform or OpenTofu plan and comments the verdict on the pull request:
72
- `uses: moneytool/aegis-devops-action@v1` with `plan: plan.json`.
72
+ Then ask Claude Code to delete the `prod` namespace: the hook blocks the command before it runs.
73
+ Gemini CLI: `gemini extensions install https://github.com/moneytool/aegis-devops`. Codex, GitHub
74
+ Copilot (CLI and VS Code), Cursor and OpenCode: `aegis install codex|copilot|vscode|cursor|opencode`
75
+ (see [Coding agents](docs/agents.md)). Aegis only acts in projects with a `.aegis/` policy, and
76
+ only blocks what that policy blocks. `aegis init` writes example rules signed with a public
77
+ example key; replace both before relying on it ([Configuration](docs/configuration.md)). It
78
+ works alongside RBAC and your agent's own permission settings; see
79
+ [Why not RBAC](#why-not-rbac-or-the-agents-own-permission-settings).
80
+
81
+ In CI, the [Aegis-DevOps Plan Check](https://github.com/marketplace/actions/aegis-devops-plan-check)
82
+ Action checks a Terraform or OpenTofu plan on every pull request
83
+ (`uses: moneytool/aegis-devops-action@v1` with `plan: plan.json`); `aegis check terraform
84
+ plan.json --exit-style ci` does the same in any pipeline, and Aegis also works as a Python
85
+ library ([Quick start](#quick-start)).
73
86
 
74
87
  ## What it does
75
88
 
@@ -226,6 +239,45 @@ about who wrote a rule, but it cannot recompute a hash or fetch a source. Up to
226
239
  rows were scored against all 500 rules, which counted rules the models never saw as resisted
227
240
  poison and understated their susceptibility (0.23–0.33); see [`CHANGELOG.md`](CHANGELOG.md).
228
241
 
242
+ ## Why not RBAC, or the agent's own permission settings?
243
+
244
+ Keep both. Aegis sits alongside them; it doesn't replace either.
245
+
246
+ **Agent permission settings** (Claude Code's allow/deny rules, Copilot's tool approvals and
247
+ similar) decide which commands an agent may run without asking you. They match the command
248
+ text. Claude Code's documentation says a Bash deny rule ["isn't a security boundary around the
249
+ program"](https://code.claude.com/docs/en/permissions#bash-rule-limits), and recommends a
250
+ PreToolUse hook when you need to inspect the full command before it runs. Aegis is that hook. It
251
+ works out what the command will do, so every spelling of the same action reaches the same rule:
252
+
253
+ | Command the agent writes | Aegis with the example policy |
254
+ |---|---|
255
+ | `kubectl delete deploy web -n prod` | BLOCK (`no-delete-in-prod-namespace`) |
256
+ | `kubectl -n prod delete deploy web` | BLOCK, same rule |
257
+ | `/usr/bin/kubectl …`, `sudo kubectl …`, `env kubectl …` | BLOCK, same rule |
258
+ | `bash -c 'kubectl delete deploy web -n prod'` | BLOCK, same rule |
259
+ | `cd /tmp && kubectl delete deploy web -n prod` | BLOCK, same rule |
260
+ | `git -C . push --force origin main` | BLOCK (`git-block-force-push-main`) |
261
+ | `K=kubectl; $K delete deploy web -n prod` | Refused: it can't be checked statically, so the hook denies it and asks for the command on its own |
262
+
263
+ Permission settings also record *what* is allowed, not who decided it. An Aegis rule only gets a
264
+ vote if nobody has changed it since it was signed and its author was allowed to write that kind
265
+ of rule.
266
+
267
+ **RBAC and IAM** decide what an identity may do. A coding agent usually runs with the
268
+ developer's own kubeconfig and cloud credentials, so RBAC sees the developer and grants the
269
+ agent the same rights. Aegis decides each action against the policy: no deletes in the `prod`
270
+ namespace, no `kubectl --as` impersonation, no plan that deletes a database. Once agents do have
271
+ their own identities, the same policy compiles into the platform layer, so it holds even for
272
+ calls that never pass through the hook (an SDK script, a leaked key):
273
+
274
+ - `aegis compile aws`: Service Control Policies scoped to agent identities.
275
+ - `aegis compile kubernetes`: ValidatingAdmissionPolicies scoped to agent identities, plus
276
+ `aegis audit-identity kubernetes` to report the RBAC permissions that would let an agent get
277
+ around them (impersonation, editing admission policies, RBAC escalation).
278
+
279
+ Both are previews; see [server-side enforcement](docs/server-side.md).
280
+
229
281
  ## Why not OPA/Gatekeeper?
230
282
 
231
283
  OPA/Gatekeeper evaluates **structured API objects** against **hand-authored rules**. Aegis
@@ -256,7 +308,12 @@ context a rule can arrive from a ticket or a chat message as easily as from you.
256
308
 
257
309
  The engine (constraint store, interceptor, environment mapping, dry-run handling, rate limits,
258
310
  plan-level constraints, and parsers for every tool in "Supported tools") is complete, and
259
- v0.3.2 is on PyPI as an **alpha**. Real LLM baselines have been run: Claude Sonnet 5 through
311
+ v1.1.0 is on PyPI, with the [session budget cap](docs/budget.md) and denial reports for the
312
+ server-side layer (`aegis report aws`, `aegis report kubernetes`). **1.0 is a promise about the
313
+ interface:** the policy file formats, the CLI commands and exit codes, the hook protocol and the
314
+ Action's inputs and outputs stay compatible until 2.0; the server-side compilers and the
315
+ identity audit remain previews ([CHANGELOG](CHANGELOG.md)). It is not a claim that the open gaps
316
+ below are closed. Real LLM baselines have been run: Claude Sonnet 5 through
260
317
  the API (cached in `results/llm-external.md`), Haiku through the Claude Code CLI, `gpt-6-astra`
261
318
  through the Codex CLI, and a local `mistral:latest`.
262
319
 
@@ -274,11 +331,13 @@ of anything you care about.
274
331
 
275
332
  | Page | Covers |
276
333
  | :--- | :--- |
334
+ | [`docs/guides/`](docs/guides/README.md) | Task-first guides: stop Claude Code, Cursor, Codex, Copilot or Gemini CLI from running destructive commands; block risky Terraform plans in CI |
277
335
  | [`docs/agents.md`](docs/agents.md) | Claude Code, Codex, Copilot, VS Code and Cursor: install, what gets blocked |
278
336
  | [`docs/cli.md`](docs/cli.md) | Exit codes, store health, the Claude Code hook, argv forms, compound commands, dry runs, library usage |
279
337
  | [`docs/constraints.md`](docs/constraints.md) | Writing constraints, metadata vocabulary, authority policy, environment mapping |
280
338
  | [`docs/configuration.md`](docs/configuration.md) | Configuration/config-dir discovery, signing, source verification, the identity model (`agents.yaml`), rate limits & ledger |
281
339
  | [`docs/server-side.md`](docs/server-side.md) | Preview: compiling the policy to AWS Service Control Policies scoped to agent identities |
340
+ | [`docs/budget.md`](docs/budget.md) | The session budget cap: per-session and per-project-per-day limits in estimated USD or tokens, across Claude Code, Codex, Gemini CLI, OpenCode and Copilot CLI |
282
341
  | [`docs/benchmark.md`](docs/benchmark.md) | Benchmark methodology, full results table, real LLM baselines, agent-harness baselines, corpus, adversarial suite |
283
342
  | [`docs/CONTRIBUTING.md`](docs/CONTRIBUTING.md) | Adding a new parser or tool |
284
343
  | [`docs/dev/PLAN.md`](docs/dev/PLAN.md) | Design plan and open gaps |
@@ -289,7 +348,7 @@ of anything you care about.
289
348
  ## Development
290
349
 
291
350
  ```bash
292
- venv/bin/python -m pytest -q # 1257 passed (last full green run; CI runs this on 3.11/3.13/3.14)
351
+ venv/bin/python -m pytest -q # 1,791 passed (CI runs this on 3.11/3.13/3.14, Linux and macOS)
293
352
  venv/bin/python -m ruff check src tests scripts examples
294
353
  vhs docs/demo.tape # regenerate docs/demo.gif
295
354
  ```
@@ -299,6 +358,12 @@ Reporting a bypass: see [`SECURITY.md`](SECURITY.md) — parser evasion is the l
299
358
  attack surface and the most useful thing to report. Release history is in
300
359
  [`CHANGELOG.md`](CHANGELOG.md).
301
360
 
361
+ ## Support
362
+
363
+ If Aegis-DevOps is useful to you, a ⭐ on [GitHub](https://github.com/moneytool/aegis-devops)
364
+ helps other people find it. Bug reports, ideas and bypasses are welcome too: open an issue, or
365
+ see [`SECURITY.md`](SECURITY.md) for anything that gets a blocked command through.
366
+
302
367
  ## License
303
368
 
304
369
  Apache-2.0 — see [LICENSE](LICENSE).
@@ -13,30 +13,43 @@ become policy.
13
13
 
14
14
  ![Aegis-DevOps blocking an injected kubectl delete](docs/where-it-sits.gif)
15
15
 
16
- ### Install in Claude Code
16
+ ## Try it in 60 seconds
17
+
18
+ **1. Watch it block a pull request (nothing to install).** Open the demo's
19
+ [example PR](https://github.com/moneytool/aegis-devops-demo/pull/1): it deletes a production
20
+ database, and the failing check is Aegis blocking it, with the verdict posted as a comment. Fork
21
+ the [demo repository](https://github.com/moneytool/aegis-devops-demo) to try your own change; no
22
+ cloud account needed.
23
+
24
+ **2. Check a command yourself:**
17
25
 
18
26
  ```bash
19
27
  pip install aegis-devops && aegis init .aegis
20
- claude plugin marketplace add moneytool/aegis-devops
21
- claude plugin install aegis-devops@aegis-devops
28
+ aegis check command --pretty -- "kubectl delete namespace prod" # BLOCK (exit 3)
29
+ aegis check command --pretty -- "kubectl get pods -n prod" # ALLOW (exit 0)
22
30
  ```
23
31
 
24
- ### Install in Gemini CLI
32
+ **3. Put it in front of your coding agent.** In the same project:
25
33
 
26
34
  ```bash
27
- pip install aegis-devops && aegis init .aegis
28
- gemini extensions install https://github.com/moneytool/aegis-devops
35
+ claude plugin marketplace add moneytool/aegis-devops
36
+ claude plugin install aegis-devops@aegis-devops
29
37
  ```
30
38
 
31
- Codex, GitHub Copilot (CLI and VS Code), Cursor and OpenCode:
32
- `aegis install codex|copilot|vscode|cursor|opencode`
33
- (see [Coding agents](docs/agents.md)). It only acts in projects with a `.aegis/` policy, and
34
- only blocks what that policy blocks. It also works as a CI step
35
- (`aegis check terraform plan.json --exit-style ci`) and as a Python library; see
36
- [Quick start](#quick-start). In GitHub Actions, the
37
- [Aegis-DevOps Plan Check](https://github.com/marketplace/actions/aegis-devops-plan-check) Action
38
- checks a Terraform or OpenTofu plan and comments the verdict on the pull request:
39
- `uses: moneytool/aegis-devops-action@v1` with `plan: plan.json`.
39
+ Then ask Claude Code to delete the `prod` namespace: the hook blocks the command before it runs.
40
+ Gemini CLI: `gemini extensions install https://github.com/moneytool/aegis-devops`. Codex, GitHub
41
+ Copilot (CLI and VS Code), Cursor and OpenCode: `aegis install codex|copilot|vscode|cursor|opencode`
42
+ (see [Coding agents](docs/agents.md)). Aegis only acts in projects with a `.aegis/` policy, and
43
+ only blocks what that policy blocks. `aegis init` writes example rules signed with a public
44
+ example key; replace both before relying on it ([Configuration](docs/configuration.md)). It
45
+ works alongside RBAC and your agent's own permission settings; see
46
+ [Why not RBAC](#why-not-rbac-or-the-agents-own-permission-settings).
47
+
48
+ In CI, the [Aegis-DevOps Plan Check](https://github.com/marketplace/actions/aegis-devops-plan-check)
49
+ Action checks a Terraform or OpenTofu plan on every pull request
50
+ (`uses: moneytool/aegis-devops-action@v1` with `plan: plan.json`); `aegis check terraform
51
+ plan.json --exit-style ci` does the same in any pipeline, and Aegis also works as a Python
52
+ library ([Quick start](#quick-start)).
40
53
 
41
54
  ## What it does
42
55
 
@@ -193,6 +206,45 @@ about who wrote a rule, but it cannot recompute a hash or fetch a source. Up to
193
206
  rows were scored against all 500 rules, which counted rules the models never saw as resisted
194
207
  poison and understated their susceptibility (0.23–0.33); see [`CHANGELOG.md`](CHANGELOG.md).
195
208
 
209
+ ## Why not RBAC, or the agent's own permission settings?
210
+
211
+ Keep both. Aegis sits alongside them; it doesn't replace either.
212
+
213
+ **Agent permission settings** (Claude Code's allow/deny rules, Copilot's tool approvals and
214
+ similar) decide which commands an agent may run without asking you. They match the command
215
+ text. Claude Code's documentation says a Bash deny rule ["isn't a security boundary around the
216
+ program"](https://code.claude.com/docs/en/permissions#bash-rule-limits), and recommends a
217
+ PreToolUse hook when you need to inspect the full command before it runs. Aegis is that hook. It
218
+ works out what the command will do, so every spelling of the same action reaches the same rule:
219
+
220
+ | Command the agent writes | Aegis with the example policy |
221
+ |---|---|
222
+ | `kubectl delete deploy web -n prod` | BLOCK (`no-delete-in-prod-namespace`) |
223
+ | `kubectl -n prod delete deploy web` | BLOCK, same rule |
224
+ | `/usr/bin/kubectl …`, `sudo kubectl …`, `env kubectl …` | BLOCK, same rule |
225
+ | `bash -c 'kubectl delete deploy web -n prod'` | BLOCK, same rule |
226
+ | `cd /tmp && kubectl delete deploy web -n prod` | BLOCK, same rule |
227
+ | `git -C . push --force origin main` | BLOCK (`git-block-force-push-main`) |
228
+ | `K=kubectl; $K delete deploy web -n prod` | Refused: it can't be checked statically, so the hook denies it and asks for the command on its own |
229
+
230
+ Permission settings also record *what* is allowed, not who decided it. An Aegis rule only gets a
231
+ vote if nobody has changed it since it was signed and its author was allowed to write that kind
232
+ of rule.
233
+
234
+ **RBAC and IAM** decide what an identity may do. A coding agent usually runs with the
235
+ developer's own kubeconfig and cloud credentials, so RBAC sees the developer and grants the
236
+ agent the same rights. Aegis decides each action against the policy: no deletes in the `prod`
237
+ namespace, no `kubectl --as` impersonation, no plan that deletes a database. Once agents do have
238
+ their own identities, the same policy compiles into the platform layer, so it holds even for
239
+ calls that never pass through the hook (an SDK script, a leaked key):
240
+
241
+ - `aegis compile aws`: Service Control Policies scoped to agent identities.
242
+ - `aegis compile kubernetes`: ValidatingAdmissionPolicies scoped to agent identities, plus
243
+ `aegis audit-identity kubernetes` to report the RBAC permissions that would let an agent get
244
+ around them (impersonation, editing admission policies, RBAC escalation).
245
+
246
+ Both are previews; see [server-side enforcement](docs/server-side.md).
247
+
196
248
  ## Why not OPA/Gatekeeper?
197
249
 
198
250
  OPA/Gatekeeper evaluates **structured API objects** against **hand-authored rules**. Aegis
@@ -223,7 +275,12 @@ context a rule can arrive from a ticket or a chat message as easily as from you.
223
275
 
224
276
  The engine (constraint store, interceptor, environment mapping, dry-run handling, rate limits,
225
277
  plan-level constraints, and parsers for every tool in "Supported tools") is complete, and
226
- v0.3.2 is on PyPI as an **alpha**. Real LLM baselines have been run: Claude Sonnet 5 through
278
+ v1.1.0 is on PyPI, with the [session budget cap](docs/budget.md) and denial reports for the
279
+ server-side layer (`aegis report aws`, `aegis report kubernetes`). **1.0 is a promise about the
280
+ interface:** the policy file formats, the CLI commands and exit codes, the hook protocol and the
281
+ Action's inputs and outputs stay compatible until 2.0; the server-side compilers and the
282
+ identity audit remain previews ([CHANGELOG](CHANGELOG.md)). It is not a claim that the open gaps
283
+ below are closed. Real LLM baselines have been run: Claude Sonnet 5 through
227
284
  the API (cached in `results/llm-external.md`), Haiku through the Claude Code CLI, `gpt-6-astra`
228
285
  through the Codex CLI, and a local `mistral:latest`.
229
286
 
@@ -241,11 +298,13 @@ of anything you care about.
241
298
 
242
299
  | Page | Covers |
243
300
  | :--- | :--- |
301
+ | [`docs/guides/`](docs/guides/README.md) | Task-first guides: stop Claude Code, Cursor, Codex, Copilot or Gemini CLI from running destructive commands; block risky Terraform plans in CI |
244
302
  | [`docs/agents.md`](docs/agents.md) | Claude Code, Codex, Copilot, VS Code and Cursor: install, what gets blocked |
245
303
  | [`docs/cli.md`](docs/cli.md) | Exit codes, store health, the Claude Code hook, argv forms, compound commands, dry runs, library usage |
246
304
  | [`docs/constraints.md`](docs/constraints.md) | Writing constraints, metadata vocabulary, authority policy, environment mapping |
247
305
  | [`docs/configuration.md`](docs/configuration.md) | Configuration/config-dir discovery, signing, source verification, the identity model (`agents.yaml`), rate limits & ledger |
248
306
  | [`docs/server-side.md`](docs/server-side.md) | Preview: compiling the policy to AWS Service Control Policies scoped to agent identities |
307
+ | [`docs/budget.md`](docs/budget.md) | The session budget cap: per-session and per-project-per-day limits in estimated USD or tokens, across Claude Code, Codex, Gemini CLI, OpenCode and Copilot CLI |
249
308
  | [`docs/benchmark.md`](docs/benchmark.md) | Benchmark methodology, full results table, real LLM baselines, agent-harness baselines, corpus, adversarial suite |
250
309
  | [`docs/CONTRIBUTING.md`](docs/CONTRIBUTING.md) | Adding a new parser or tool |
251
310
  | [`docs/dev/PLAN.md`](docs/dev/PLAN.md) | Design plan and open gaps |
@@ -256,7 +315,7 @@ of anything you care about.
256
315
  ## Development
257
316
 
258
317
  ```bash
259
- venv/bin/python -m pytest -q # 1257 passed (last full green run; CI runs this on 3.11/3.13/3.14)
318
+ venv/bin/python -m pytest -q # 1,791 passed (CI runs this on 3.11/3.13/3.14, Linux and macOS)
260
319
  venv/bin/python -m ruff check src tests scripts examples
261
320
  vhs docs/demo.tape # regenerate docs/demo.gif
262
321
  ```
@@ -266,6 +325,12 @@ Reporting a bypass: see [`SECURITY.md`](SECURITY.md) — parser evasion is the l
266
325
  attack surface and the most useful thing to report. Release history is in
267
326
  [`CHANGELOG.md`](CHANGELOG.md).
268
327
 
328
+ ## Support
329
+
330
+ If Aegis-DevOps is useful to you, a ⭐ on [GitHub](https://github.com/moneytool/aegis-devops)
331
+ helps other people find it. Bug reports, ideas and bypasses are welcome too: open an issue, or
332
+ see [`SECURITY.md`](SECURITY.md) for anything that gets a blocked command through.
333
+
269
334
  ## License
270
335
 
271
336
  Apache-2.0 — see [LICENSE](LICENSE).
@@ -25,7 +25,7 @@ keywords = [
25
25
  "context-poisoning",
26
26
  ]
27
27
  classifiers = [
28
- "Development Status :: 3 - Alpha",
28
+ "Development Status :: 4 - Beta",
29
29
  "Environment :: Console",
30
30
  "Intended Audience :: System Administrators",
31
31
  "Intended Audience :: Developers",
@@ -63,7 +63,7 @@ version = {attr = "aegis_core.__version__"}
63
63
  where = ["src"]
64
64
 
65
65
  [tool.setuptools.package-data]
66
- aegis_core = ["_examples/**/*", "integrations/*", "compile/actions/*"]
66
+ aegis_core = ["_examples/**/*", "integrations/*", "compile/actions/*", "budget/*.yaml", "budget/*.json"]
67
67
 
68
68
  [tool.ruff]
69
69
  line-length = 100
@@ -4,4 +4,4 @@ infrastructure actions of AI agents.
4
4
  See the README for what this does and, importantly, what it does not yet do.
5
5
  """
6
6
 
7
- __version__ = "0.3.2"
7
+ __version__ = "1.1.0"
@@ -34,6 +34,9 @@ trusted:
34
34
  - platform: aws
35
35
  kind: source-identity
36
36
  id: alice@example.com
37
+ # A source identity survives role chaining, so an agent started in alice's session would
38
+ # carry it and be exempt. Trust one only if no agent ever runs under it, and say so:
39
+ no_agents: true
37
40
  - platform: github
38
41
  kind: oidc-subject
39
42
  # bound to one reusable workflow at a protected ref, so an agent job in the same
@@ -0,0 +1,2 @@
1
+ aegis-sig-v1
2
+ 2b55b41fc96166220d0d092f84dfee805ee18f791b5181c4b850836c7148042c
@@ -6,6 +6,7 @@ principals:
6
6
  - deletion
7
7
  - configuration
8
8
  - identity # may change agents.yaml, the identity model
9
+ - budget # may change budget.yaml, the budget cap
9
10
  sre_lead:
10
11
  - scaling
11
12
  - configuration
@@ -0,0 +1,2 @@
1
+ aegis-sig-v1
2
+ b2ceb3e6cb27ac15787c4d6b9015065e03b804a6ac837c8fcc4f9895961bd130
@@ -0,0 +1,21 @@
1
+ # The session budget cap (docs/budget.md). Copy to budget.yaml, set your own limits, and sign
2
+ # it with `aegis sign`; its principal must hold the 'budget' class in authority.yaml. Until
3
+ # it is named budget.yaml it does nothing. Then reinstall your agents' hooks (`aegis install
4
+ # <agent>`) so they see every tool call, and check with: aegis budget status
5
+ version: 1
6
+ principal: admin # must hold the 'budget' class in authority.yaml
7
+ unit: usd # usd (estimated from list prices) | tokens; required
8
+ session:
9
+ limit: 20 # per agent session
10
+ warn_at: 0.8 # warn once at 80%
11
+ project_day:
12
+ limit: 100 # every measured session in this project, per day
13
+ warn_at: 0.8
14
+ tz: UTC # the day boundary
15
+ agents: [claude, codex, gemini, opencode, copilot] # only listed agents are measured
16
+ on_unknown_log: allow # allow (warn) | deny: usage Aegis cannot verify
17
+ on_unknown_price: estimate # estimate (warn) | deny: models with no price
18
+ pricing: {} # signed overrides, USD per million tokens:
19
+ # claude-opus-5-5: {input: 4, output: 20, cache_read: 0.2, cache_write: 8}
20
+ copilot:
21
+ premium_requests: 50 # Copilot CLI reports premium requests, not tokens
@@ -0,0 +1,2 @@
1
+ aegis-sig-v1
2
+ d8ad9e56f8548c60028c05c17ce2f46ca190127cbafde00669faef484f3eaea4
@@ -0,0 +1,27 @@
1
+ """Cross-agent session budget cap (design: docs/dev/DESIGN-v1.0-budget-cap.md).
2
+
3
+ * :mod:`~aegis_core.budget.policy` -- the signed ``budget.yaml``;
4
+ * :mod:`~aegis_core.budget.pricing` -- tokens to estimated dollars;
5
+ * :mod:`~aegis_core.budget.logs` -- reading usage from each agent's logs;
6
+ * :mod:`~aegis_core.budget.accounting` -- session records, project/day
7
+ totals, revisions, locks, the inventory and rebuilds;
8
+ * :mod:`~aegis_core.budget.evaluate` -- allow / warn / deny.
9
+ """
10
+
11
+ from aegis_core.budget.accounting import BudgetStore, Snapshot, rebuild, refresh
12
+ from aegis_core.budget.evaluate import ALLOW, DENY, WARN, Verdict, evaluate
13
+ from aegis_core.budget.logs import Locator, default_logs
14
+ from aegis_core.budget.policy import BUDGET_CLASS, BUDGET_FILE, BudgetPolicy, load_budget_policy
15
+ from aegis_core.budget.pricing import PriceTable, load_builtin_table
16
+
17
+
18
+ def price_table(policy: BudgetPolicy) -> PriceTable:
19
+ """The built-in prices with the policy's signed overrides."""
20
+ return PriceTable(load_builtin_table(), policy.pricing)
21
+
22
+
23
+ __all__ = [
24
+ "ALLOW", "BUDGET_CLASS", "BUDGET_FILE", "DENY", "WARN", "BudgetPolicy", "BudgetStore",
25
+ "Locator", "PriceTable", "Snapshot", "Verdict", "default_logs", "evaluate",
26
+ "load_budget_policy", "load_builtin_table", "price_table", "rebuild", "refresh",
27
+ ]