P0 security batch: true global admin, quota gates on all spending paths, default quota for quota-less users, fix-review author trust + docker/owner attribution, GitHub App setup issuer binding, real cancel kill, wider shell env exclusion
- CODEX_GLOBAL_ADMINS replaces maintainer-derived global admin; admin endpoints (quotas, sweep, backup, push dispatch) fail-closed 403 when unset, with audit on allow and deny. - continue/followups/messages/retry check both caller and original creator quotas (USD + unpriced token cap), 402 on either overrun. - Quota-less users now get the #86 default quota instead of unlimited; init_db backfills and OAuth create/bind/existing-login branches INSERT OR IGNORE a default row; explicit NULL row stays unlimited. user_quotas added to migration tables. - /fix-review: untrusted authors rejected before dedup claim, no task; trusted tasks force executor=docker, created_by=project owner, owner quota gate, prompt is a fixed template plus a 2000-char excerpt. - GitHub App setup state only issued by global admins, state rows bind issued_by (ALTER-compatible for old DBs), callback rejects issuers no longer in the admin list without consuming the state. - Cancel: popen poll checks DB status every second, Docker path runs a cancel watchdog that kills by container name, write-back is CAS-guarded so late results never overwrite a new status. - SHELL_ENV_EXCLUDE adds *_TOKEN, *_AUTH*, *_CREDENTIAL*, *API_KEY*; comment states the residual risk: same-UID /proc environ remains readable, true isolation needs UID separation or hidepid. - Tests: new cloud/tests/test_p0_security.py (17 cases); old tests updated to the new semantics (admin env, default quota, trusted fix-review author) without weakening any gate.
This commit is contained in:
1 parent
d0ca1f7f60
commit
7091a2d0d2
13 files changed
+1017
-146
No files matched your search
@@ -289,6 +289,10 @@ class AppHttpTestCase(unittest.TestCase):
|
||||
self.db_path = os.path.join(self.tmp.name, "control.db")
|
||||
self.auth = AuthStore(self.db_path)
|
||||
self.user_a, self.key_a = self.auth.create_user("user-a")
|
||||
# P0 安全批后:setup state 只限全局管理员,本用例里
|
||||
# user-a 即管理员。
|
||||
self._old_admins = os.environ.get("CODEX_GLOBAL_ADMINS")
|
||||
os.environ["CODEX_GLOBAL_ADMINS"] = self.user_a
|
||||
self.server = create_server(self.db_path, "127.0.0.1", 0)
|
||||
self.port = self.server.server_address[1]
|
||||
self.thread = threading.Thread(
|
||||
@@ -307,6 +311,10 @@ class AppHttpTestCase(unittest.TestCase):
|
||||
self.tmp.cleanup()
|
||||
os.environ.pop("GITHUB_APP_PUBLIC_BASE", None)
|
||||
os.environ.pop("GITHUB_WEBHOOK_SECRET", None)
|
||||
if self._old_admins is None:
|
||||
os.environ.pop("CODEX_GLOBAL_ADMINS", None)
|
||||
else:
|
||||
os.environ["CODEX_GLOBAL_ADMINS"] = self._old_admins
|
||||
|
||||
def _req(self, method, path, body=None, key=None, headers=None):
|
||||
conn = http.client.HTTPConnection("127.0.0.1", self.port, timeout=10)
|
||||
@@ -488,7 +496,8 @@ class AppHttpTestCase(unittest.TestCase):
|
||||
payload = {
|
||||
"action": "created",
|
||||
"comment": {"id": 777, "body": "please /fix-review this",
|
||||
"user": {"login": "octo"}},
|
||||
"user": {"login": "octo",
|
||||
"author_association": "COLLABORATOR"}},
|
||||
"issue": {"number": 5},
|
||||
"repository": {"full_name": "octo/a"}}
|
||||
# 同一评论送两遍,delivery_id 不同(模拟手动 + App 双通道)。
|
||||
|
||||
Reference in new issue
Block a user