Skip to content

[codex] add user-scoped WebUI tool approvals#5251

Closed
think-in-universe wants to merge 39 commits into
mainfrom
codex/multi-tenant-tool-approvals
Closed

[codex] add user-scoped WebUI tool approvals#5251
think-in-universe wants to merge 39 commits into
mainfrom
codex/multi-tenant-tool-approvals

Conversation

@think-in-universe

Copy link
Copy Markdown
Collaborator

Fixes #5242

Summary

  • Add caller-scoped approval stores for global auto-approve, persistent approvals, and per-tool overrides.
  • Add authenticated WebUI v2 settings routes for listing tools, changing per-tool permission state, and toggling global auto-approve without requiring operator config access.
  • Wire local-dev active extension capabilities into the WebUI tool catalog, preserving hard-floor denial for sensitive tools.
  • Update the settings frontend to use the new user-scoped tool endpoints and refresh cached tool settings after changes.

Security / tenancy

  • Operator config remains operator-only. These new settings routes resolve state for the authenticated caller scope.
  • Global auto-approve is keyed by tenant and user, not by operator-only config.
  • Hard-floor tools such as financial, approval-modifying, and budget-modifying capabilities remain locked out of auto-approval.

Notes

  • Cargo.lock also includes Cargo 1.92 lockfile normalization for optional ironclaw_reborn_openai_compat deps already declared in that crate; cargo +1.92.0 metadata --locked passes after the lockfile update.

Tests

  • cargo +1.92.0 test -p ironclaw_approvals
  • cargo +1.92.0 test -p ironclaw_product_workflow --lib tool_permissions_are_user_scoped_and_apply_persistent_policy
  • cargo +1.92.0 test -p ironclaw_webui_v2 --features webui-v2-beta every_descriptor_matches_the_locked_policy_surface
  • cargo +1.92.0 check -p ironclaw_reborn_composition --features webui-v2-beta
  • cargo +1.92.0 metadata --locked --format-version 1
  • git diff --check

hanakannzashi and others added 30 commits June 4, 2026 19:48
* feat(reborn): add OpenAI-compatible product refs

* fix(reborn): validate OpenAI-compatible ref mappings

* fix(reborn): address OpenAI product refs review

* Validate durable OpenAI compat ref records

* Format OpenAI compat storage review fixes

---------

Co-authored-by: Robert Yan <mstr.raphael@gmail.com>
@railway-app railway-app Bot temporarily deployed to ironclaw-ci-preview / ironclaw-pr-5251 June 25, 2026 16:37 Destroyed
@coderabbitai

coderabbitai Bot commented Jun 25, 2026

Copy link
Copy Markdown

Important

Review skipped

Draft detected.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 25a56a37-7bf1-4591-8bf9-d32d09c9b7f5

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/multi-tenant-tool-approvals

Comment @coderabbitai help to get the list of available commands.

@github-actions github-actions Bot added scope: docs Documentation scope: dependencies Dependency updates size: XL 500+ changed lines risk: low Changes to docs, tests, or low-risk modules contributor: core 20+ merged PRs labels Jun 25, 2026

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Code Review

This pull request introduces user-scoped tool permission settings, auto-approval stores, and persistent approval policies, integrating them into the WebUI. It also implements ProductWorkflow-backed, non-streaming Chat Completions and Responses workflows within the OpenAI-compatible API layer, alongside SSE streaming translation for projection-backed streams. Feedback on the changes suggests improving robustness in both the chat and responses workflows by logging failures in binding internal references rather than propagating the errors and failing otherwise successful client requests.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment on lines +232 to +234
Ok(result) => {
let _ = result?;
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

If bind_internal_refs fails at the end of a successful chat completion, propagating the error with result? will fail the entire client request. Since the turn has already run and completed successfully, it is much more robust to log the error and proceed to return the successful response to the user.

                Ok(result) => {
                    if let Err(err) = result {
                        tracing::error!(
                            public_id = public_id.as_str(),
                            error = ?err,
                            "failed to bind internal refs; continuing to return successful response"
                        );
                    }
                }

Comment on lines +189 to +192
if let Some(internal_refs) = wait_result.internal_refs {
self.bind_internal_refs(caller.scope().clone(), public_id, internal_refs)
.await?;
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

Similarly, if bind_internal_refs fails at the end of a successful response completion, propagating the error with ? will fail the entire client request. Since the turn has already run and completed successfully, it is much more robust to log the error and proceed to return the successful response to the user.

        if let Some(internal_refs) = wait_result.internal_refs {
            if let Err(err) = self.bind_internal_refs(caller.scope().clone(), public_id, internal_refs).await {
                tracing::error!(
                    public_id = public_id.as_str(),
                    error = ?err,
                    "failed to bind internal refs; continuing to return successful response"
                );
            }
        }

@railway-app

railway-app Bot commented Jun 25, 2026

Copy link
Copy Markdown

🚅 Deployed to the ironclaw-pr-5251 environment in ironclaw-ci-preview

Service Status Web Updated (UTC)
ironclaw ❌ Build Failed (View Logs) Web Jun 25, 2026 at 4:37 pm

@think-in-universe

Copy link
Copy Markdown
Collaborator Author

Closing this draft in favor of a clean replacement branch based directly on current main.

@think-in-universe think-in-universe deleted the codex/multi-tenant-tool-approvals branch June 25, 2026 17:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

contributor: core 20+ merged PRs risk: low Changes to docs, tests, or low-risk modules scope: dependencies Dependency updates scope: docs Documentation size: XL 500+ changed lines

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Reborn] Tools page under Settings shows operator-only tools error for WebUI users

2 participants