Skip to content

Add audited Admin control plane - #88

Merged
Svaag merged 18 commits into
mainfrom
agent/admin-control-plane
Sep 27, 2026
Merged

Svaag merged 18 commits into
mainfrom
agent/admin-control-plane

Conversation

@Svaag

@Svaag Svaag commented Jul 21, 2026 •

Copy link
Copy Markdown
Contributor

Operators need authenticated, audited access to account and resource state, durable suspension/resumption work, and an explicit distinction between waived usage and settled revenue. Add the admin control plane and interactive hyrule-admin create bootstrap, reconciled with current main's checkout ownership, catalog readiness gates, provisioning events and domain-settlement recovery.

Browser-only admin sessions require session-bound CSRF protection; real-cost operations require recent password step-up. Disabled accounts are enforced, private routes are excluded from public OpenAPI and return no-store responses, and operations write audit records. API bearer credentials cannot compose with admin privilege. A supplied real x402 signature retains precedence over waivers. Waivers are disabled by default, rate-limited through durable records, and recorded separately from charged revenue; waived failures do not create fictitious refund obligations.

Validation: the reconciled full suite passed 758 tests with 11 warnings. The separate optional PostgreSQL 16.10 test passed the real empty → 020 → 023 → 020 → 023 migration path with fixture accounts and paid/development VM billing backfills. Existing account/VM rows survived the roundtrip. Ruff, full mypy on 110 source files and diff checks passed. The database fixture was network-isolated and removed with its test volume. No production data or services were changed.

Migration 023 currently follows 020; the former admin revision 017 conflicted with the already-deployed provisioning-events migration and is no longer used. Reconcile the parent with pending expiry/guest migrations before merge if they land first, retaining a single head and rerunning migration validation. A downgrade removes admin audit/operation tables and columns; preserve that history and reconcile outstanding operations before considering it. The test proves account/VM row preservation, not audit retention across schema rollback.

Rollout requires green CI, resolved review and the normal infrastructure pinned-SHA promotion workflow, with API/worker quiescence and provisioning preflight from network-operations PR547. Verify the live schema, API/worker health, session/CSRF behavior and an audited read-only admin view. Bootstrap only through the interactive CLI; keep payment waivers disabled until the companion frontend and audit paths are verified. See docs/runbooks/admin-promotion.md.

This is the admin foundation. The operator expiry-extension endpoint, scheduled expiry notices and recoverable disk retention from #110 remain separate outstanding work. Companion frontend: hyrule-web PR45.

@github-actions

Copy link
Copy Markdown

Failed to generate code suggestions for PR

@Svaag
Svaag marked this pull request as ready for review July 21, 2026 18:21
@Svaag

Svaag commented Jul 21, 2026

Copy link
Copy Markdown
Contributor Author

@codex review

@github-actions

Copy link
Copy Markdown

Failed to generate code suggestions for PR

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 5a3cd447c0

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread hyrule_cloud/api/routes.py
Comment thread hyrule_cloud/middleware/x402.py Outdated
Comment thread hyrule_cloud/services/admin_operations.py Outdated
Comment thread hyrule_cloud/domains/wallet_auth.py
Comment thread hyrule_cloud/services/admin_operations.py Outdated
Comment thread hyrule_cloud/api/admin.py

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 62c0650651

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread hyrule_cloud/api/admin.py
Comment thread hyrule_cloud/app.py Outdated
Comment thread hyrule_cloud/api/admin.py
Comment thread hyrule_cloud/middleware/x402.py
Comment thread alembic/versions/023_admin_console.py
@Svaag

Svaag commented Jul 21, 2026

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: cf742a08bf

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread hyrule_cloud/middleware/x402.py Outdated
Comment thread hyrule_cloud/services/admin_operations.py Outdated
Comment thread hyrule_cloud/api/admin.py Outdated
Comment thread hyrule_cloud/api/admin.py Outdated
Comment thread hyrule_cloud/api/admin.py
Comment thread hyrule_cloud/middleware/x402.py
@Svaag

Svaag commented Jul 21, 2026

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 68d5024d12

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread hyrule_cloud/api/admin.py
Comment thread hyrule_cloud/services/admin_operations.py
Comment thread hyrule_cloud/services/admin_operations.py Outdated
Comment thread hyrule_cloud/api/admin.py Outdated
Comment thread hyrule_cloud/domains/api.py
Comment thread hyrule_cloud/api/routes.py
@Svaag

Svaag commented Jul 21, 2026

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 209241ef93

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread hyrule_cloud/services/admin_operations.py Outdated
Comment thread hyrule_cloud/api/admin.py Outdated
Comment thread hyrule_cloud/api/admin.py Outdated
Comment thread hyrule_cloud/middleware/x402.py Outdated
@Svaag

Svaag commented Jul 21, 2026

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 880f9ddba5

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread hyrule_cloud/services/admin_operations.py Outdated
Comment thread hyrule_cloud/api/admin.py
Comment thread hyrule_cloud/api/admin.py
Comment thread hyrule_cloud/api/admin.py
Comment thread alembic/versions/023_admin_console.py
Comment thread hyrule_cloud/middleware/x402.py Outdated
Comment thread hyrule_cloud/services/admin_operations.py
@Svaag

Svaag commented Jul 21, 2026

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: e861225fb6

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread hyrule_cloud/orchestrator.py
Comment thread hyrule_cloud/api/admin.py
Comment thread hyrule_cloud/api/routes.py Outdated
Comment thread alembic/versions/017_admin_console.py Outdated
Comment thread hyrule_cloud/api/admin.py
@Svaag

Svaag commented Jul 21, 2026

Copy link
Copy Markdown
Contributor Author

@codex review

@Svaag

Svaag commented Jul 21, 2026

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: ff15883975

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread hyrule_cloud/api/admin.py Outdated
Comment thread hyrule_cloud/orchestrator.py Outdated
Comment thread hyrule_cloud/domains/service.py
Comment thread hyrule_cloud/api/admin.py
Comment thread hyrule_cloud/api/admin.py
@Svaag

Svaag commented Jul 21, 2026

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 96b6627baf

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread alembic/versions/017_admin_console.py Outdated
Comment thread hyrule_cloud/api/routes.py Outdated
Comment thread hyrule_cloud/middleware/x402.py
Comment thread hyrule_cloud/api/admin.py Outdated
@Svaag

Svaag commented Jul 21, 2026

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 0fd5e122cd

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread hyrule_cloud/orchestrator.py Outdated
Comment thread hyrule_cloud/api/admin.py Outdated
Comment thread hyrule_cloud/api/routes.py Outdated
Comment thread hyrule_cloud/admin_cli.py Outdated
Comment thread hyrule_cloud/worker.py Outdated
@Svaag

Svaag commented Jul 22, 2026

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 206e0964be

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread hyrule_cloud/api/admin.py Outdated
@Svaag

Svaag commented Jul 22, 2026

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 02eba1ba43

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread hyrule_cloud/api/admin.py Outdated
Comment thread hyrule_cloud/api/admin.py
Comment thread hyrule_cloud/api/admin.py Outdated
Comment thread hyrule_cloud/api/admin.py
@Svaag

Svaag commented Jul 22, 2026

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. 🎉

Reviewed commit: 07d5fe97b4

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 8, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-09-27T14:18:01.173377Z 1c73528 New commits
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@Svaag

Svaag commented Sep 8, 2026

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 009f46e239

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +668 to +669
if owner_account_id and row.owner_account_id is None:
row.owner_account_id = owner_account_id

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Fence the account assigned at activation

For an anonymous EVM checkout, the reservation's expected_owner_account_id is None, but _bind_payer_account() can resolve the paying wallet to an existing disabled account; this assignment then attaches that account without locking or checking it. If its suspension operation already completed while the reservation was ownerless, provisioning starts afterward and leaves a live VM owned by the disabled account. The fresh evidence beyond the earlier reservation-fence finding is that the new check covers only the reservation's pre-payment owner, not the effective owner_account_id assigned here.

Useful? React with 👍 / 👎.

Comment thread hyrule_cloud/orchestrator.py Outdated
.limit(1)
)
).scalar_one_or_none()
await self.refunds.record_owed(

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Make extension refund writes durable

When an extension fails after x402 settlement, this calls RefundService.record_owed(), whose underlying PaymentLedger.record_event() deliberately swallows persistence failures. A transient ledger/database failure therefore lets this method return normally and the route report that a refund was recorded even though no obligation exists and no recovery job will recreate it; use a required write or another durable retry mechanism for this financial record.

Useful? React with 👍 / 👎.

Comment on lines +430 to +433
operation = match_paid_operation(request.method, request.url.path)
if operation is None:
raise HTTPException(status_code=403, detail="admin_bypass_unclassified")
return operation.admin_operation_class

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Treat tunnel creation as real-cost

For /v1/tunnel/create, the matched catalog operation has no class override, so this returns its default diagnostic classification. An Admin session without recent password step-up can consequently provision live reverse-tunnel leases at the 120-per-minute diagnostic limit instead of the 10-per-hour real-cost limit, potentially exhausting the daemon's finite public-port pool; classify tunnel creation as real_cost before granting its waiver.

Useful? React with 👍 / 👎.

Comment on lines +3057 to +3060
extra["amount_received_crypto"] = (
str(native_intent.amount_received_crypto)
if native_intent.amount_received_crypto is not None
else None

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Report only the refundable crypto share for kept-VM bundles

When a BTC/XMR domain-plus-VM bundle uses KEEP_VM and domain fulfillment fails, _fail_paid_order() correctly limits amount_usd to domain_amount_usd, but this copies the intent's full bundle payment into amount_received_crypto. The Admin refund response presents that field as the native amount to return, so an operator can refund the entire crypto payment while the customer keeps the provisioned VM; persist the prorated refundable crypto amount or clearly separate total received from the amount owed.

Useful? React with 👍 / 👎.

Comment thread hyrule_cloud/admin_cli.py
config = HyruleConfig()
engine = create_db_engine(config.database_url)
try:
await init_db(engine)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Avoid mutating an unmigrated database during Admin bootstrap

If hyrule-admin create is accidentally run before revision 023, this init_db() call invokes Base.metadata.create_all(): against a revision-020 database it commits the new Admin tables but cannot add the new columns to existing tables, after which the bootstrap query fails on accounts.disabled_at. The database is then left partially upgraded and a subsequent alembic upgrade fails when it tries to create those already-created tables; the CLI should verify the Alembic head and fail without mutation rather than running create_all().

Useful? React with 👍 / 👎.

Comment thread hyrule_cloud/worker.py
Comment on lines +234 to +235
stop.set()
await admin_operations_task

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Bound shutdown waiting for Admin operations

During worker shutdown, setting stop does not interrupt an Admin operation already inside process_admin_operations(), and this unconditional await blocks until its entire batch finishes. Since each operation can make sequential provider calls for many VMs and an XO exchange alone can wait up to 300 seconds, a deployment or SIGTERM can exceed its termination grace period before providers and the database are closed; cancel or timeout-and-cancel this task while leaving its durable running row for stale recovery.

Useful? React with 👍 / 👎.

Comment thread hyrule_cloud/api/admin.py
Comment on lines +816 to +817
enabled_admin_count = await _enabled_admin_count(session, lock=True)
target = await _locked_account(session, account_id)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Revalidate the acting Admin inside mutation transactions

A privileged request keeps the detached actor accepted by the dependency but never locks or reloads that account or its session before mutating state. With three Admins, for example, B can enter this endpoint and block on the enabled-Admin lock while A disables B; after A commits and revokes B's sessions, B resumes with the stale actor, observes A and C as the two enabled Admins, and can still disable C. Revalidate the actor's enabled Admin role and live elevated session under the mutation transaction so demotion, disable, and session revocation fence already-started requests.

Useful? React with 👍 / 👎.

Comment thread hyrule_cloud/api/admin.py Outdated
Comment on lines +1114 to +1117
async with _factory(state)() as session:
row = await session.get(VMRow, vm_id)
if row is None:
raise HTTPException(404, "VM not found")

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Serialize destroy actions with ownership transfers

The final fenced power-action branch explicitly excludes destroy, so this lookup releases its session before provider and database cleanup. If a VM transfer commits while destroy_vm() is deleting the provider instance, the transfer can return success and assign the attached domain to the recipient, after which destroy marks the VM destroyed and attempts domain detachment using the old owner captured before the transfer; that detachment can fail and leave the recipient's domain attached to a deleted VM. Hold the VM/domain ownership fence through destroy dispatch and persistence, using the same lock order as transfers.

Useful? React with 👍 / 👎.

Main already carries the audited admin console plus expiry retention.
Keep that tree so this branch can merge without reverting it.

Assisted-by: pi-coding-agent:grok-4.7
@Svaag
Svaag merged commit 4543c7d into main Sep 27, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant