Skip to content

fix(platform): Fix Google Drive auto-credentials handling across the platform - #12004

Closed
ntindle wants to merge 9 commits into
devfrom
ntindle/google-issues-fix
Closed

fix(platform): Fix Google Drive auto-credentials handling across the platform#12004
ntindle wants to merge 9 commits into
devfrom
ntindle/google-issues-fix

Conversation

@ntindle

@ntindle ntindle commented Feb 6, 2026

Copy link
Copy Markdown
Member

Google Drive file picker blocks embed a _credentials_id in the file field data, but the platform had no way to distinguish these "auto-credentials" from regular user-provided credentials. This caused auto-credentials to appear in UI credential forms, CoPilot "missing credentials" prompts, and library preset guards — confusing users. Additionally, forking an agent didn't clear the embedded credential references, so cloned agents could silently use the original author's Google credentials. Finally, Firefox's strict referrer policy was blocking Google API script loads.

Changes 🏗️

Backend — Data model (model.py, block.py, graph.py)

  • CredentialsFieldInfo gains is_auto_credential and input_field_name fields to tag auto-credentials
  • BlockSchema.get_auto_credentials_fields() returns auto-credential metadata for execution
  • Graph.regular_credentials_inputs / auto_credentials_inputs properties filter aggregated credentials
  • _reassign_ids() clears _credentials_id on fork to prevent cross-user credential leakage
  • combine() and discriminate() propagate is_auto_credential and input_field_name

Backend — Executor (manager.py, utils.py)

  • _acquire_auto_credentials() extracted as standalone async helper to resolve embedded _credentials_id at execution time with Redis lock management
  • _validate_node_input_credentials() validates auto-credential ownership before execution
  • make_node_credentials_input_map() uses regular_credentials_inputs only

Backend — CoPilot & Library (chat/tools/utils.py, library/db.py)

  • build_missing_credentials_from_graph() and match_user_credentials_to_graph() use regular_credentials_inputs so auto-credentials aren't reported as "missing"
  • Library preset guard uses regular_credentials_inputs

Frontend (GoogleDrivePicker/helpers.ts)

  • Adds referrerPolicy: "no-referrer-when-downgrade" to both Google API script loads (gapi + picker) to fix Firefox blocking

Known deferred: run_block.py (CoPilot RunBlockTool) still includes auto-credentials in credential matching — tracked as SECRT-1911

Checklist 📋

For code changes:

  • I have clearly listed my changes in the PR description
  • I have made a test plan
  • I have tested my changes according to the test plan:
    • manager_auto_credentials_test.py — 6 tests covering credential acquisition, error cases, chained data
    • utils_test.py — 8 tests covering auto-credential validation, fork clearing, mixed credential graphs
    • graph_test.py — 5 tests covering regular_credentials_inputs, auto_credentials_inputs, schema exclusion, combine(), discriminate() propagation
    • chat/tools/utils_test.py — 2 tests covering CoPilot credential filtering
    • All 916 existing tests pass (84 skipped, 0 failures)
    • All pre-commit hooks pass (linting, formatting, typechecking)

For configuration changes:

  • .env.default is updated or already compatible with my changes
  • docker-compose.yml is updated or already compatible with my changes
  • I have included a list of my configuration changes in the PR description (under Changes) — N/A, no configuration changes

Note

Medium Risk
Touches credential schema aggregation and executor credential acquisition/validation paths; while well-tested, mistakes could block runs or incorrectly prompt for credentials across many agents.

Overview
Fixes Google Drive auto-credentials end-to-end by tagging them in CredentialsFieldInfo (is_auto_credential, input_field_name) and splitting graph credential aggregation into regular_credentials_inputs vs auto_credentials_inputs, so only regular creds appear in graph schemas, CoPilot “missing credentials” prompts, credential mapping, and preset eligibility checks.

Strengthens execution-time handling for file-embedded _credentials_id: forks now strip _credentials_id to prevent cross-user credential reuse, executor validation checks auto-credential ownership/missing auth, and execution resolves auto-creds via a new _acquire_auto_credentials() helper with clearer error messages; adds extensive regression tests and sets referrerPolicy on Google script loads to avoid Firefox blocking.

Written by Cursor Bugbot for commit c42aab3. This will update automatically on new commits. Configure here.

…platform

- Tag auto-credentials with `is_auto_credential` and `input_field_name` on `CredentialsFieldInfo` to distinguish them from regular user-provided credentials
- Add `regular_credentials_inputs` and `auto_credentials_inputs` properties to `Graph` so UI schemas, CoPilot, and library presets only surface regular credentials
- Extract `_acquire_auto_credentials()` helper in executor to resolve embedded `_credentials_id` at execution time with proper lock management
- Validate auto-credentials ownership in `_validate_node_input_credentials()` to catch stale/missing credentials before execution
- Clear `_credentials_id` in `_reassign_ids()` on graph fork so cloned agents require re-authentication
- Propagate `is_auto_credential` through `combine()` and `discriminate()` on `CredentialsFieldInfo`
- Add `referrerPolicy: "no-referrer-when-downgrade"` to Google API script loading to fix Firefox API key validation
- Comprehensive test coverage for all new behavior

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@ntindle
ntindle requested a review from a team as a code owner February 6, 2026 22:10
@ntindle
ntindle requested review from Bentlybro, Pwuts and Copilot and removed request for a team February 6, 2026 22:10
@github-project-automation github-project-automation Bot moved this to 🆕 Needs initial review in AutoGPT development kanban Feb 6, 2026
@github-actions github-actions Bot added platform/frontend AutoGPT Platform - Front end platform/backend AutoGPT Platform - Back end labels Feb 6, 2026
@github-actions

github-actions Bot commented Feb 6, 2026

Copy link
Copy Markdown
Contributor

This pull request has conflicts with the base branch, please resolve those so we can evaluate the pull request.

@github-actions github-actions Bot added the conflicts Automatically applied to PRs with merge conflicts label Feb 6, 2026
@coderabbitai

coderabbitai Bot commented Feb 6, 2026

Copy link
Copy Markdown
Contributor

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

Adds metadata to credential fields to distinguish auto vs regular credentials; exposes Graph.regular_credentials_inputs and Graph.auto_credentials_inputs; clears _credentials_id on Graph._reassign_ids; excludes auto-credentials from static matching/presets; implements runtime auto-credential acquisition/validation with tests and a small frontend script tweak.

Changes

Cohort / File(s) Summary
Core model & graph
autogpt_platform/backend/backend/data/model.py, autogpt_platform/backend/backend/data/graph.py
Add is_auto_credential and input_field_name to CredentialsFieldInfo; propagate them in combine()/discriminate(); add Graph.regular_credentials_inputs and Graph.auto_credentials_inputs; clear _credentials_id in Graph._reassign_ids.
Block schema
autogpt_platform/backend/backend/data/block.py
Mark auto-generated credential fields with is_auto_credential: True and set input_field_name to the source input field.
Executor: acquisition & validation
autogpt_platform/backend/backend/executor/manager.py, autogpt_platform/backend/backend/executor/utils.py, autogpt_platform/backend/backend/executor/manager_auto_credentials_test.py, autogpt_platform/backend/backend/executor/utils_test.py
Introduce _acquire_auto_credentials helper; centralize runtime auto-credential acquisition in execute_node; add validation paths for auto_credentials; adjust static credential mapping to use regular_credentials_inputs; add unit tests for acquisition, locking, and validation branches.
Chat tools & library
autogpt_platform/backend/backend/api/features/chat/tools/utils.py, autogpt_platform/backend/backend/api/features/chat/tools/utils_test.py, autogpt_platform/backend/backend/api/features/library/db.py
Switch static uses of aggregate_credentials_inputs() to regular_credentials_inputs to exclude auto-credentials from build/match/preset flows; add tests ensuring auto-credentials are excluded from static matching.
Graph tests & behaviors
autogpt_platform/backend/backend/data/graph_test.py
Add tests covering credential metadata propagation, _credentials_id cleanup on reassign, schema exposure rules (regular vs auto), and related edge cases.
Frontend script load
autogpt_platform/frontend/src/components/contextual/GoogleDrivePicker/helpers.ts
Add referrerPolicy option when loading Google API / Identity scripts.

Sequence Diagram

sequenceDiagram
    participant Client
    participant Executor
    participant Graph
    participant CredManager as "Creds Manager"

    Client->>Executor: execute_node(block, input_data, user_id)
    Executor->>Graph: get_auto_credentials_fields()
    Graph-->>Executor: auto_credentials fields

    rect rgba(100,200,100,0.5)
    loop per auto_credential field
        Executor->>Executor: extract field_data and _credentials_id
        alt _credentials_id present
            Executor->>CredManager: acquire(user_id, cred_id)
            CredManager-->>Executor: credentials + lock
            Executor->>Executor: inject credentials into exec_kwargs
        else _credentials_id missing or None
            Executor->>Executor: skip or raise (per field rules)
        end
    end
    end

    Executor->>Executor: run node with exec_kwargs
    Executor->>CredManager: release credential locks (finally)
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested labels

Possible security concern, Review effort 5/5

Suggested reviewers

  • Pwuts
  • Bentlybro

Poem

🐇 I hop through keys both old and new,
Auto creds fetched when files point true,
Regulars stay mapped out of sight,
Locks held tight until the job is right,
A rabbit cheers this credential flight!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Linked Issues check ⚠️ Warning The PR implements most objectives from SECRT-1911 (auto-credential handling in executor, validation, credential resolution) but explicitly defers RunBlockTool auto-credentials implementation (CoPilot's run_block.py), which is the core requirement of the linked issue. Complete the RunBlockTool auto-credentials handling in run_block.py by iterating get_auto_credentials_fields() and injecting _credentials_id-referenced credentials into exec_kwargs, as outlined in SECRT-1911 and documented in the PR description.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The PR title 'fix(platform): Fix Google Drive auto-credentials handling across the platform' directly and clearly describes the main change — separating auto-credentials from regular credentials across the platform.
Out of Scope Changes check ✅ Passed All changes align with the goal of fixing auto-credentials handling: data model extensions, executor refactoring, CoPilot/library credential filtering, and frontend Google script loading. No unrelated changes detected.
Docstring Coverage ✅ Passed Docstring coverage is 80.77% which is sufficient. The required threshold is 80.00%.
Description check ✅ Passed The pull request description comprehensively details the changes, addressing Google Drive auto-credentials handling with clear sections for backend, executor, CoPilot/Library, and frontend changes, plus test coverage and a known deferred item.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch ntindle/google-issues-fix

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

Copilot AI 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.

Pull request overview

This PR improves Google Drive “auto-credentials” handling end-to-end by explicitly tagging auto-generated credentials, excluding them from user-facing credential mapping flows, validating ownership earlier, and resolving embedded _credentials_id at execution time with clearer error behavior (plus a small frontend fix for Google script loading in Firefox).

Changes:

  • Adds is_auto_credential + input_field_name to CredentialsFieldInfo and propagates them through combine()/discriminate().
  • Introduces Graph.regular_credentials_inputs / Graph.auto_credentials_inputs and updates executor/chat/library flows to use regular credentials only for UI/schema/matching.
  • Extracts _acquire_auto_credentials() in the executor and adds auto-credential validation; updates Google script loading with referrerPolicy.

Reviewed changes

Copilot reviewed 12 out of 12 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
autogpt_platform/frontend/src/components/contextual/GoogleDrivePicker/helpers.ts Sets script referrerPolicy for Google API loaders.
autogpt_platform/backend/backend/executor/utils_test.py Adds tests covering auto-credential validation and regular-only mapping.
autogpt_platform/backend/backend/executor/utils.py Validates auto-credentials and maps only regular graph credentials inputs.
autogpt_platform/backend/backend/executor/manager_auto_credentials_test.py New test suite for _acquire_auto_credentials() behavior and edge cases.
autogpt_platform/backend/backend/executor/manager.py Extracts auto-credential acquisition helper and wires it into node execution.
autogpt_platform/backend/backend/data/model.py Adds auto-credential fields to CredentialsFieldInfo and propagates in combine/discriminate.
autogpt_platform/backend/backend/data/graph_test.py Adds tests for propagation, schema exclusion, and fork clearing of _credentials_id.
autogpt_platform/backend/backend/data/graph.py Adds regular_credentials_inputs/auto_credentials_inputs and clears _credentials_id on fork.
autogpt_platform/backend/backend/data/block.py Tags auto-credentials in get_credentials_fields_info() output.
autogpt_platform/backend/backend/api/features/library/db.py Uses regular_credentials_inputs to gate preset creation.
autogpt_platform/backend/backend/api/features/chat/tools/utils_test.py New tests ensuring chat tools exclude auto-credentials.
autogpt_platform/backend/backend/api/features/chat/tools/utils.py Switches credential aggregation to regular_credentials_inputs.

Comment thread autogpt_platform/backend/backend/data/model.py
Comment thread autogpt_platform/backend/backend/executor/manager.py
Comment thread autogpt_platform/backend/backend/executor/utils.py
Comment thread autogpt_platform/backend/backend/data/model.py
Comment thread autogpt_platform/backend/backend/executor/manager.py
Comment thread autogpt_platform/backend/backend/data/graph.py
Comment thread autogpt_platform/backend/backend/executor/utils.py Outdated
Adapt auto-credentials filtering to dev's refactored graph model:
- aggregate_credentials_inputs() now returns 3-tuples (field_info, node_pairs, is_required)
- credentials_input_schema moved to GraphModel, builds JSON schema directly
- Update regular/auto_credentials_inputs properties for 3-tuple format
- Update test mocks and assertions for new tuple format and class hierarchy

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@ntindle
ntindle requested review from majdyz and removed request for Pwuts February 6, 2026 22:40
@github-actions github-actions Bot removed the conflicts Automatically applied to PRs with merge conflicts label Feb 6, 2026
@github-actions

github-actions Bot commented Feb 6, 2026

Copy link
Copy Markdown
Contributor

Conflicts have been resolved! 🎉 A maintainer will review the pull request shortly.

@coderabbitai coderabbitai 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.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
autogpt_platform/backend/backend/api/features/chat/tools/utils.py (1)

226-248: ⚠️ Potential issue | 🟡 Minor

Stale docstring references aggregate_credentials_inputs().

Line 233 still says "Uses graph.aggregate_credentials_inputs()" but the implementation now uses regular_credentials_inputs. This will confuse future readers.

📝 Proposed fix
-    Uses graph.aggregate_credentials_inputs() which handles credentials from
-    multiple nodes and uses frozensets for provider matching.
+    Uses graph.regular_credentials_inputs which handles credentials from
+    multiple nodes (excluding auto-credentials) and uses frozensets for provider matching.
🤖 Fix all issues with AI agents
In `@autogpt_platform/backend/backend/executor/utils.py`:
- Around line 355-366: The auto-credentials branch calling get_creds_by_id on
creds_store (in the block handling field_value dicts) lacks error handling and
can raise from the credentials store; wrap the await
creds_store.get_creds_by_id(user_id, cred_id) call in a try/except like the
regular credentials path so store failures set has_missing_credentials=True and
populate credential_errors[node.id][field_name] with an appropriate message
(include context that the credentials store failed) instead of letting the
exception propagate; reference get_integration_credentials_store,
creds_store.get_creds_by_id, credential_errors, node.id, and field_name when
making the change.
📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between e00c120 and 8b7053c.

📒 Files selected for processing (9)
  • autogpt_platform/backend/backend/api/features/chat/tools/utils.py
  • autogpt_platform/backend/backend/api/features/chat/tools/utils_test.py
  • autogpt_platform/backend/backend/api/features/library/db.py
  • autogpt_platform/backend/backend/data/block.py
  • autogpt_platform/backend/backend/data/graph.py
  • autogpt_platform/backend/backend/data/graph_test.py
  • autogpt_platform/backend/backend/data/model.py
  • autogpt_platform/backend/backend/executor/utils.py
  • autogpt_platform/backend/backend/executor/utils_test.py
🚧 Files skipped from review as they are similar to previous changes (4)
  • autogpt_platform/backend/backend/data/model.py
  • autogpt_platform/backend/backend/api/features/library/db.py
  • autogpt_platform/backend/backend/data/block.py
  • autogpt_platform/backend/backend/api/features/chat/tools/utils_test.py
🧰 Additional context used
📓 Path-based instructions (10)
autogpt_platform/backend/**/*.py

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

autogpt_platform/backend/**/*.py: Use Python 3.11 (required; managed by Poetry via pyproject.toml) for backend development
Always run 'poetry run format' (Black + isort) before linting in backend development
Always run 'poetry run lint' (ruff) after formatting in backend development

Files:

  • autogpt_platform/backend/backend/executor/utils.py
  • autogpt_platform/backend/backend/api/features/chat/tools/utils.py
  • autogpt_platform/backend/backend/data/graph_test.py
  • autogpt_platform/backend/backend/executor/utils_test.py
  • autogpt_platform/backend/backend/data/graph.py
autogpt_platform/backend/**/*.{py,txt}

📄 CodeRabbit inference engine (autogpt_platform/backend/CLAUDE.md)

Use poetry run prefix for all Python commands, including testing, linting, formatting, and migrations

Files:

  • autogpt_platform/backend/backend/executor/utils.py
  • autogpt_platform/backend/backend/api/features/chat/tools/utils.py
  • autogpt_platform/backend/backend/data/graph_test.py
  • autogpt_platform/backend/backend/executor/utils_test.py
  • autogpt_platform/backend/backend/data/graph.py
autogpt_platform/backend/backend/**/*.py

📄 CodeRabbit inference engine (autogpt_platform/backend/CLAUDE.md)

Use Prisma ORM for database operations in PostgreSQL with pgvector for embeddings

Files:

  • autogpt_platform/backend/backend/executor/utils.py
  • autogpt_platform/backend/backend/api/features/chat/tools/utils.py
  • autogpt_platform/backend/backend/data/graph_test.py
  • autogpt_platform/backend/backend/executor/utils_test.py
  • autogpt_platform/backend/backend/data/graph.py
autogpt_platform/**/*.py

📄 CodeRabbit inference engine (AGENTS.md)

Format Python code with poetry run format

Files:

  • autogpt_platform/backend/backend/executor/utils.py
  • autogpt_platform/backend/backend/api/features/chat/tools/utils.py
  • autogpt_platform/backend/backend/data/graph_test.py
  • autogpt_platform/backend/backend/executor/utils_test.py
  • autogpt_platform/backend/backend/data/graph.py
autogpt_platform/backend/backend/api/features/**/*.py

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Update routes in '/backend/backend/api/features/' and add/update Pydantic models in the same directory for API development

When modifying API routes, update corresponding Pydantic models in the same directory and write tests alongside the route file

Files:

  • autogpt_platform/backend/backend/api/features/chat/tools/utils.py
autogpt_platform/backend/backend/api/**/*.py

📄 CodeRabbit inference engine (autogpt_platform/backend/CLAUDE.md)

autogpt_platform/backend/backend/api/**/*.py: Use FastAPI for building REST and WebSocket endpoints
Use JWT-based authentication with Supabase integration

Files:

  • autogpt_platform/backend/backend/api/features/chat/tools/utils.py
autogpt_platform/backend/backend/data/**/*.py

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

All data access in backend requires user ID checks; verify this for any 'data/*.py' changes

Files:

  • autogpt_platform/backend/backend/data/graph_test.py
  • autogpt_platform/backend/backend/data/graph.py
autogpt_platform/backend/**/*_test.py

📄 CodeRabbit inference engine (autogpt_platform/backend/CLAUDE.md)

autogpt_platform/backend/**/*_test.py: Always review snapshot changes with git diff before committing when updating snapshots with poetry run pytest --snapshot-update
Use pytest with snapshot testing for API responses in test files
Colocate test files with source files using the *_test.py naming convention

Files:

  • autogpt_platform/backend/backend/data/graph_test.py
  • autogpt_platform/backend/backend/executor/utils_test.py
autogpt_platform/backend/**/*test*.py

📄 CodeRabbit inference engine (AGENTS.md)

Run poetry run test for backend testing (runs pytest with docker based postgres + prisma)

Files:

  • autogpt_platform/backend/backend/data/graph_test.py
  • autogpt_platform/backend/backend/executor/utils_test.py
autogpt_platform/**/data/*.py

📄 CodeRabbit inference engine (AGENTS.md)

For changes touching data/*.py, validate user ID checks or explain why not needed

Files:

  • autogpt_platform/backend/backend/data/graph_test.py
  • autogpt_platform/backend/backend/data/graph.py
🧠 Learnings (2)
📚 Learning: 2026-02-04T16:50:51.303Z
Learnt from: CR
Repo: Significant-Gravitas/AutoGPT PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-02-04T16:50:51.303Z
Learning: Applies to autogpt_platform/**/data/*.py : For changes touching `data/*.py`, validate user ID checks or explain why not needed

Applied to files:

  • autogpt_platform/backend/backend/executor/utils.py
  • autogpt_platform/backend/backend/data/graph.py
📚 Learning: 2026-02-04T16:49:42.476Z
Learnt from: CR
Repo: Significant-Gravitas/AutoGPT PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2026-02-04T16:49:42.476Z
Learning: Applies to autogpt_platform/backend/**/test/**/*.py : Use snapshot testing with '--snapshot-update' flag in backend tests when output changes; always review with 'git diff'

Applied to files:

  • autogpt_platform/backend/backend/data/graph_test.py
  • autogpt_platform/backend/backend/executor/utils_test.py
🧬 Code graph analysis (4)
autogpt_platform/backend/backend/executor/utils.py (4)
autogpt_platform/backend/backend/data/graph.py (2)
  • block (131-140)
  • regular_credentials_inputs (607-615)
autogpt_platform/backend/backend/data/block.py (1)
  • get_auto_credentials_fields (274-302)
autogpt_platform/backend/backend/util/clients.py (1)
  • get_integration_credentials_store (113-117)
autogpt_platform/backend/backend/integrations/credentials_store.py (1)
  • get_creds_by_id (382-386)
autogpt_platform/backend/backend/api/features/chat/tools/utils.py (1)
autogpt_platform/backend/backend/data/graph.py (1)
  • regular_credentials_inputs (607-615)
autogpt_platform/backend/backend/data/graph_test.py (2)
autogpt_platform/backend/backend/data/model.py (3)
  • CredentialsFieldInfo (566-696)
  • combine (578-673)
  • discriminate (675-696)
autogpt_platform/backend/backend/data/graph.py (3)
  • Graph (378-381)
  • name (1713-1714)
  • _reassign_ids (646-686)
autogpt_platform/backend/backend/executor/utils_test.py (4)
autogpt_platform/backend/backend/executor/utils.py (2)
  • _validate_node_input_credentials (239-380)
  • make_node_credentials_input_map (383-416)
autogpt_platform/backend/backend/data/graph.py (1)
  • regular_credentials_inputs (607-615)
autogpt_platform/backend/backend/data/model.py (2)
  • CredentialsFieldInfo (566-696)
  • CredentialsMetaInput (496-554)
autogpt_platform/backend/backend/integrations/providers.py (1)
  • ProviderName (6-108)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (10)
  • GitHub Check: Seer Code Review
  • GitHub Check: e2e_test
  • GitHub Check: types
  • GitHub Check: Seer Code Review
  • GitHub Check: Cursor Bugbot
  • GitHub Check: test (3.11)
  • GitHub Check: test (3.12)
  • GitHub Check: test (3.13)
  • GitHub Check: Analyze (python)
  • GitHub Check: Check PR Status
🔇 Additional comments (10)
autogpt_platform/backend/backend/data/graph.py (2)

606-626: LGTM — clean separation of regular vs. auto credentials.

The filter-based properties are straightforward and correctly delegate to aggregate_credentials_inputs(). The is_auto_credential flag on the tuple's first element is the right discriminator.

One minor note: both properties independently call aggregate_credentials_inputs(), so if both are accessed in the same code path the aggregation runs twice. This isn't a concern today (not a hot path), but worth keeping in mind if usage grows.


678-686: Good security hardening — clearing _credentials_id on fork.

The loop correctly targets only dict-typed values containing _credentials_id, leaving other fields intact. This prevents credential leakage when a graph is forked to another user.

autogpt_platform/backend/backend/api/features/chat/tools/utils.py (1)

120-120: LGTM — auto-credentials correctly excluded from missing-credentials computation.

autogpt_platform/backend/backend/executor/utils_test.py (2)

918-972: Good test coverage for auto-credential validation paths.

The four auto-credential validation tests (valid, missing, both, None-skip) provide solid coverage of the _validate_node_input_credentials auto-credential branch. The mock structures correctly mirror the get_auto_credentials_fields() return format.


1192-1241: make_node_credentials_input_map exclusion test is solid.

The test correctly verifies that only regular credentials appear in the output map by asserting no _credentials_id values leak through. The mock of regular_credentials_inputs as a property (rather than aggregate_credentials_inputs) matches the production code path.

autogpt_platform/backend/backend/executor/utils.py (2)

343-366: Auto-credentials validation logic looks correct.

The implementation properly:

  • Extracts _credentials_id from file-field data
  • Skips when _credentials_id is None (upstream-chained)
  • Validates ownership via get_creds_by_id
  • Reports a user-friendly error when credentials aren't found

One thing to note: the error message on line 363 is hardcoded to "Google credentials". If auto-credentials expand beyond Google Drive in the future, this will need generalization.


399-401: LGTM — make_node_credentials_input_map correctly scoped to regular credentials only.

autogpt_platform/backend/backend/data/graph_test.py (3)

466-526: Good regression tests for combine() field propagation.

Both tests (auto and regular) verify that is_auto_credential and input_field_name survive the combine operation. These directly guard against the bug class described in the PR.


531-673: Thorough _reassign_ids credential clearing tests.

Good coverage of edge cases: single credential field, preserving non-credential fields, no credentials present, and multiple credential fields. These directly validate the security fix.


728-789: credentials_input_schema exclusion test is well-structured.

Using PropertyMock to control regular_credentials_inputs isolates the schema generation logic cleanly.

✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.

Comment thread autogpt_platform/backend/backend/executor/utils.py
Wrap get_creds_by_id call in try/except in the auto-credentials
validation path to match the error handling pattern used for regular
credentials.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@qodo-code-review

Copy link
Copy Markdown
ⓘ Your monthly quota for Qodo has expired. Upgrade your plan
ⓘ Paying users. Check that your Qodo account is linked with this Git user account

4 similar comments
@qodo-code-review

Copy link
Copy Markdown
ⓘ Your monthly quota for Qodo has expired. Upgrade your plan
ⓘ Paying users. Check that your Qodo account is linked with this Git user account

@qodo-code-review

Copy link
Copy Markdown
ⓘ Your monthly quota for Qodo has expired. Upgrade your plan
ⓘ Paying users. Check that your Qodo account is linked with this Git user account

@qodo-code-review

Copy link
Copy Markdown
ⓘ Your monthly quota for Qodo has expired. Upgrade your plan
ⓘ Paying users. Check that your Qodo account is linked with this Git user account

@qodo-code-review

Copy link
Copy Markdown
ⓘ Your monthly quota for Qodo has expired. Upgrade your plan
ⓘ Paying users. Check that your Qodo account is linked with this Git user account

Resolved conflicts:
- executor/utils.py: kept auto-credentials validation + dev's comment update
- graph_test.py: kept both auto-credentials tests AND MCP deduplication tests
@github-actions

Copy link
Copy Markdown
Contributor

Conflicts have been resolved! 🎉 A maintainer will review the pull request shortly.

@github-actions github-actions Bot removed the conflicts Automatically applied to PRs with merge conflicts label Feb 16, 2026
@github-actions

Copy link
Copy Markdown
Contributor

🔍 PR Overlap Detection

This check compares your PR against all other open PRs targeting the same branch to detect potential merge conflicts early.

🔴 Merge Conflicts Detected

The following PRs have been tested and will have merge conflicts if merged after this PR. Consider coordinating with the authors.

  • feat(platform): Add dynamic LLM model registry with admin UI #11699 (Bentlybro · updated 2d ago)

    • .github/workflows/claude-dependabot.yml (1 conflict, ~23 lines)
    • .github/workflows/claude.yml (1 conflict, ~23 lines)
    • autogpt_platform/backend/Dockerfile (1 conflict, ~7 lines)
    • autogpt_platform/backend/backend/api/features/chat/config.py (3 conflicts, ~50 lines)
    • autogpt_platform/backend/backend/api/features/chat/routes.py (1 conflict, ~4 lines)
    • autogpt_platform/backend/backend/api/features/chat/service.py (1 conflict, ~7 lines)
    • autogpt_platform/backend/backend/api/features/chat/tools/__init__.py (2 conflicts, ~15 lines)
    • autogpt_platform/backend/backend/api/features/chat/tools/models.py (4 conflicts, ~90 lines)
    • autogpt_platform/backend/backend/api/features/chat/tools/utils.py (3 conflicts, ~31 lines)
    • autogpt_platform/backend/backend/api/rest_api.py (2 conflicts, ~14 lines)
    • autogpt_platform/backend/backend/api/ws_api.py (1 conflict, ~5 lines)
    • autogpt_platform/backend/backend/blocks/llm.py (4 conflicts, ~448 lines)
    • autogpt_platform/backend/backend/data/block_cost_config.py (3 conflicts, ~98 lines)
    • autogpt_platform/backend/backend/data/graph.py (2 conflicts, ~31 lines)
    • autogpt_platform/backend/poetry.lock (2 conflicts, ~20 lines)
    • autogpt_platform/frontend/src/app/api/openapi.json (12 conflicts, ~1078 lines)
    • docs/integrations/README.md (1 conflict, ~6 lines)
  • fix(backend): Fix static link resolving behavior on concurrent output #9593 (majdyz · updated 2d ago)

    • 📁 autogpt_platform/backend/backend/
      • data/execution.py (7 conflicts, ~283 lines)
      • executor/database.py (2 conflicts, ~59 lines)
      • executor/manager.py (5 conflicts, ~61 lines)
      • executor/manager_test.py (1 conflict, ~8 lines)
  • refactor(frontend): remove old builder code and monitoring components  #12082 (Abhi1992002 · updated 2d ago)

    • 📁 autogpt_platform/
      • backend/backend/blocks/_base.py (2 conflicts, ~9 lines)
      • frontend/src/app/(platform)/build/components/legacy-builder/Flow/Flow.tsx (modified here, deleted there)

🟢 Low Risk — File Overlap Only

These PRs touch the same files but different sections (click to expand)

Summary: 3 conflict(s), 0 medium risk, 6 low risk (out of 9 PRs with file overlap)


Auto-generated on push. Ignores: openapi.json, lock files.

@github-actions

Copy link
Copy Markdown
Contributor

This pull request has conflicts with the base branch, please resolve those so we can evaluate the pull request.

@autogpt-reviewer autogpt-reviewer 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.

📋 PR #12004 — fix(platform): Fix Google Drive auto-credentials handling across the platform

Author: ntindle | Files: 12 changed (+1238/−45) | Reviewed by: 8-specialist automated review squad


🎯 Verdict: APPROVE WITH CONDITIONS


What This PR Does

Separates "auto-credentials" (embedded in Google Drive file picker fields via _credentials_id) from regular user-provided credentials across the platform. Auto-credentials no longer appear in UI credential forms, CoPilot "missing credentials" prompts, or library preset guards. Forking an agent now clears embedded credential references to prevent cross-user credential leakage. Also fixes Firefox blocking Google API script loads via referrerPolicy.


Specialist Findings

🛡️ Security ✅ — Credential ownership is properly user-scoped via user_id in all acquire() and get_creds_by_id calls. Fork clearing in _reassign_ids() correctly prevents cross-user credential reuse. No credential leakage paths identified. Two low-severity notes: partial lock cleanup on multi-field failure (mitigated by Redis TTL) and non-recursive dict clearing (sufficient for current GoogleDriveFile model).

🏗️ Architecture ✅ — Design is fundamentally sound. The is_auto_credential/input_field_name fields on CredentialsFieldInfo are generic enough to extend to other providers. Clean separation between regular and auto credential paths. Suggestions: extract _credentials_id as a named constant (used as magic string in 4+ locations), add explicit guard in run_block.py for auto-credential blocks until SECRT-1911 is addressed, and consider a shared state-parser for the 5-state dict semantics.

Performance ⚠️regular_credentials_inputs and auto_credentials_inputs are uncached @property methods that each independently call aggregate_credentials_inputs(). In a single request flow, this can run the full aggregation 2-3x. Additionally, _validate_node_input_credentials calls get_integration_credentials_store() and get_creds_by_id per auto-credential field (N+1 pattern). Current impact is low (only Google Drive auto-creds exist), but should be cached.

🧪 Testing ✅ — Excellent coverage with ~1,056 lines of new tests across 4 files. Tests are well-structured with ticket references (SECRT-1772, OPEN-2895), descriptive names, and realistic mocks. All tests confirmed running (no skip markers), CI passes on 3.11/3.12/3.13. Gaps: no test for multi-field lock stranding failure path, no test for _credentials_id key-missing scenario in validation, no test for get_creds_by_id exception path, no test for empty-string _credentials_id.

📖 Quality ⚠️ — Strong overall. Error messages are dynamic (provider pulled from config), user-friendly, and actionable. Test organization is excellent. One item: stale docstring in match_user_credentials_to_graph() still references aggregate_credentials_inputs() instead of regular_credentials_inputs (flagged by CodeRabbit, not yet fixed).

📦 Product ✅ — Complete fix for all primary user-facing issues. All 4 consumer paths (CoPilot prompts, credential input schema, library presets, execution mapping) updated to exclude auto-credentials. Fork clearing gives users clear, actionable error messages guiding re-authentication. Firefox referrerPolicy fix uses universal browser-supported values. Deferred run_block.py gap (SECRT-1911) is narrow and well-documented.

📬 Discussion ⚠️ — PR currently has unresolved merge conflicts with base branch (since Feb 17). majdyz's APPROVE was dismissed pending comment resolution — all substantive threads are now resolved (3 real bugs fixed: missing try/except, misplaced header, fork credential clearing changed from =None to del). Follow-up PR #12016 created for code duplication concern. 2 minor items unaddressed: stale docstring and credential ID in error message.

🔎 QA ✅ — Frontend loads correctly across all pages (landing, copilot, build, marketplace, library). Google Drive File Input Block renders on canvas. Backend healthy. referrerPolicy change properly implemented in loadScript helper. No PR-related console errors. Full Google OAuth flow untestable in local env (requires real credentials), but backend logic is thoroughly unit-tested.

QA Screenshots:


Conditions (must address before merge)

  1. Resolve merge conflicts — PR has been in conflict since Feb 17. Must rebase/merge from base branch.
  2. Fix stale docstringmatch_user_credentials_to_graph() in chat/tools/utils.py:233 still references aggregate_credentials_inputs(). Update to reference regular_credentials_inputs.

Should Fix (follow-up OK)

  1. Cache aggregate_credentials_inputs() — Use @cached_property or lazy init to avoid 2-3x redundant computation per request flow (graph.py:619-637).
  2. Extract _credentials_id as named constant — Magic string used in 4+ locations across manager.py, utils.py, graph.py, _base.py. Define AUTO_CREDENTIALS_ID_KEY = "_credentials_id".
  3. Hoist get_integration_credentials_store() — Currently re-instantiated per iteration in validation loop (utils.py:369). Move outside the loop.
  4. Add run_block.py guard — Explicit check that blocks with auto-credentials can't be run via RunBlockTool until SECRT-1911 is addressed. Currently would give confusing errors.
  5. Add edge-case tests — Multi-field lock stranding, _credentials_id key-missing in validation, get_creds_by_id exception path, empty-string credential ID.

Nice to Have

  • Include credential ID in error messages for easier debugging (CodeRabbit suggestion)
  • Consistent section header formatting in graph_test.py
  • auto_credentials_inputs property is currently dead code — add a comment noting it's for future use or remove

Risk Assessment

Merge risk: LOW — Well-tested (1056 lines of new tests, CI green), security model is sound, all existing tests pass. Changes are additive (new fields/properties) with minimal modification of existing logic.

Rollback: EASY — The new fields have defaults (is_auto_credential=False, input_field_name=None), so reverting wouldn't break existing data. The fork clearing and validation are new code paths that would simply be removed.


@ntindle This is a solid, well-tested security and UX fix. The credential separation design is clean and extensible. Main blockers are the merge conflicts and one stale docstring. Once those are resolved, this is good to merge. The should-fix items (caching, constant extraction, run_block guard) can follow up.

@ntindle

ntindle commented Apr 21, 2026

Copy link
Copy Markdown
Member Author

Superseded by #12874 — merged into the combined autopilot beta blockers PR along with #12748 and #12588. Closing in favour of the combined PR.

@ntindle ntindle closed this Apr 21, 2026
auto-merge was automatically disabled April 21, 2026 22:01

Pull request was closed

@github-project-automation github-project-automation Bot moved this to Done in Frontend Apr 21, 2026
@github-project-automation github-project-automation Bot moved this from 👍🏼 Mergeable to ✅ Done in AutoGPT development kanban Apr 21, 2026
SymbolStar pushed a commit to SymbolStar/AutoGPT that referenced this pull request Apr 25, 2026
…2269) (Significant-Gravitas#12874)

### Why / What / How

**Why:** A beta user spent significant time trying to build and run
agents that read Google Sheets. Four separate failures compounded on
their session — all already open in Linear as SECRT-2266 through
SECRT-2269. Three in-flight PRs each addressed a piece but conflicted on
the same files (`backend/data/model.py`, `backend/blocks/_base.py`,
`autogpt_libs/.../types.py`), so landing them individually would have
been churn. One of the four reported issues (the credential-delete
crash) is also the top unresolved Sentry issue `AUTOGPT-SERVER-6HB` with
100+ events going back to 2025-10-20 — it was archived as "ignored" but
is a real regression. Bug Significant-Gravitas#4 required new work; the others we got by
adopting the existing open PRs and addressing a pending review comment.

**What:** This PR consolidates the three in-flight PRs, adds the two
pieces of new work needed to fully close the beta blockers, and
addresses the pending review on one of the three PRs so it doesn't
require a second round.

- **Closes PR Significant-Gravitas#12004** — Google Drive auto-credentials handling (merged
in)
- **Closes PR Significant-Gravitas#12748** — Incremental OAuth for scope upgrades (merged
in)
- **Closes PR Significant-Gravitas#12588** — superseded by the systemic None-guard here (see
"How" below)
- **Adds Bug 2 fix** — Google credential deletion no longer crashes on
`revoke_tokens`
- **Adds Bug 4 validator** — the agent builder can no longer save a
graph with a hardcoded Drive file ID

**How:**

1. **Adopt PR Significant-Gravitas#12004 (Bug 1 — auto-credentials resolution).** Tags
Drive-file fields as `is_auto_credential` on `CredentialsFieldInfo`,
exposes `BlockSchema.get_auto_credentials_fields()` and
`Graph.regular_credentials_inputs` / `auto_credentials_inputs`, extracts
`_acquire_auto_credentials()` in the executor to resolve embedded
`_credentials_id` at run time, clears `_credentials_id` on agent fork so
cloned agents don't inherit the original author's credential, and fixes
the Firefox referrer policy on the Google Drive picker script load.

2. **Adopt PR Significant-Gravitas#12748 (Bug 3 — credential accumulation).** OAuth callback
now merges scopes into an existing credential (explicit via
`credential_id` in OAuth state, or implicit via `provider + username`
match) instead of appending a new row on every reconnect. GitHub's
non-incremental OAuth path requests the union of existing + new scopes
at login so the upgrade path works there too.

3. **Replace PR Significant-Gravitas#12588 with a systemic None-guard (addresses reviewer
feedback).** The original PR added a per-block `credentials:
GoogleCredentials | None = None` + early guard pattern that would need
to be repeated across 50+ blocks with `GoogleDriveFileField`. Per the
reviewer's ask, we moved the guard into `Block._execute()` once: after
the `setdefault` loop, if `kwargs[kwarg_name] is None` we raise
`BlockExecutionError` with a clean user-facing message. The per-block
change in `sheets.py` is dropped so `credentials: GoogleCredentials`
stays non-`Optional`. Dry-run path skips the guard (executor
intentionally runs blocks without resolved creds for schema validation).

4. **Fix Bug 2 — Google revoke_tokens (SECRT-2267,
AUTOGPT-SERVER-6HB).** `revoke_tokens()` was handing our Pydantic
`OAuth2Credentials` into google-auth's `AuthorizedSession`, which calls
`self.credentials.before_request(...)` on the object and crashes with
`AttributeError: 'OAuth2Credentials' object has no attribute
'before_request'`. Google's token revoke endpoint doesn't need any auth
header — just `token=<token>` in the form body per [Google's
docs](https://developers.google.com/identity/protocols/oauth2/web-server#tokenrevoke).
Switched to the platform's async `Requests` helper, matching how
`reddit.py` / `github.py` / `todoist.py` / other providers do
revocation. No google-auth objects involved.

5. **Fix Bug 4 — hardcoded Drive file IDs in agent graphs
(SECRT-2269).** Evidence from the beta user's session: CoPilot's
agent-builder produced 13 saved graph versions in one session where each
one stuffed either a bare string (`"1KAv…"`) or a partial object
(`{"id": "1KAv…"}`) into
`GoogleSheetsReadBlock.constantInput.spreadsheet`, never wiring an
`AgentGoogleDriveFileInputBlock` as the intended input. Bare-string
versions failed pydantic validation with `is not of type 'object'`;
object-with-only-`id` versions would have crashed at run time because
`_acquire_auto_credentials` has no `_credentials_id` to resolve. Added a
validator in `GraphModel._validate_graph_get_errors` that flags any
auto-credentials field whose `input_default.<field>` is a bare string OR
a dict missing `_credentials_id`, when there's no upstream link feeding
the field. Remediation text is format-aware: when
`field_schema["format"] == "google-drive-picker"` it names
`AgentGoogleDriveFileInputBlock` specifically; for any other future
auto-credentials format (OneDrive / Dropbox / etc.) the remediation is
generic, so we don't ship a stale Google-specific hint that doesn't
apply.

A companion handoff for the CoPilot agent-builder team is drafted at
`/tmp/agent-builder-ticket-drive-file-input.md` (to be filed in their
tracker). The validator here is a safety net so reviewers and the LLM
both get a clear error with the correct remediation; the agent-builder
itself still needs to learn the correct pattern so it stops trying to
hardcode Drive files in the first place.

### Changes 🏗️

**Backend**

- `backend/data/model.py` — merged `is_auto_credential` +
`input_field_name` (Significant-Gravitas#12004) with `OAuthState.credential_id` (Significant-Gravitas#12748);
kept HEAD's defensive `set()` copy on `discriminator_values`.
- `backend/blocks/_base.py` — `_execute()` runs the auto-credentials
setdefault loop + raises `BlockExecutionError` when a resolved value is
`None`.
- `backend/blocks/google/sheets_test.py` — 2 new tests (systemic
None-guard behaviour).
- `backend/blocks/google/_drive.py`, `_drive_test.py` — unchanged on
this branch (earlier bare-string validator was reverted after feedback;
see "Out of scope" below).
- `backend/data/graph.py` — auto-credentials anti-pattern validator in
`_validate_graph_get_errors`.
- `backend/data/graph_test.py` — 11 new tests for the validator.
- `backend/integrations/oauth/google.py` — `revoke_tokens` swapped to
`Requests().post`, removed `AuthorizedSession` misuse.
- `backend/integrations/oauth/google_test.py` — 3 new tests covering the
revoke happy path, no-access-token, and non-2xx-response.
- `backend/integrations/credentials_store.py` — from Significant-Gravitas#12748.
- `backend/api/features/integrations/router.py` — incremental-OAuth
callback + scope upgrade helpers (from Significant-Gravitas#12748).
- `backend/api/features/integrations/incremental_oauth_test.py` — 15
tests (from Significant-Gravitas#12748).
- `backend/api/features/chat/tools/utils.py` → renamed to
`backend/copilot/tools/utils.py` during merge; now uses
`regular_credentials_inputs` for missing-creds + matching (from Significant-Gravitas#12004).
- `backend/copilot/tools/utils_test.py` — moved from
`api/features/chat/tools/`, import paths updated.
- `backend/api/features/library/db.py` — library preset guard uses
`regular_credentials_inputs` (from Significant-Gravitas#12004).
- `backend/data/graph.py` — `regular_credentials_inputs` /
`auto_credentials_inputs` properties + `_reassign_ids` clears
`_credentials_id` on fork (from Significant-Gravitas#12004).
- `backend/executor/manager.py` — `_acquire_auto_credentials()`
extracted + validation (from Significant-Gravitas#12004).
- `backend/executor/utils.py`, `utils_test.py`,
`manager_auto_credentials_test.py` — auto-credentials tests (from
Significant-Gravitas#12004).

**Frontend**

- `frontend/src/components/contextual/GoogleDrivePicker/helpers.ts` —
Firefox referrer fix (from Significant-Gravitas#12004).
-
`frontend/src/components/contextual/CredentialsInput/useCredentialsInput.ts`,
`src/hooks/useCredentials.ts`, `src/lib/autogpt-server-api/client.ts`,
`src/providers/agent-credentials/credentials-provider.tsx`,
`src/app/api/openapi.json` — incremental-OAuth scope upgrade UI (from
Significant-Gravitas#12748).

**Shared libs**

- `autogpt_libs/supabase_integration_credentials_store/types.py` —
merged additions from both Significant-Gravitas#12004 and Significant-Gravitas#12748.

### Test plan 📋

- [x] `poetry run lint` — clean
- [x] `poetry run pytest backend/data/graph_test.py` — 55 passed
including 11 new validator tests
- [x] `poetry run pytest backend/integrations/oauth/google_test.py` — 3
new tests passing
- [x] `poetry run pytest backend/blocks/google/sheets_test.py` — 2 new
tests passing
- [x] `poetry run pytest backend/blocks/google/
backend/integrations/oauth/ backend/executor/ backend/data/graph_test.py
backend/api/features/integrations/ backend/copilot/tools/utils_test.py`
— 250 passed, 6 pre-existing failures that require the docker stack
(RabbitMQ/Redis/Postgres) and fail identically on `origin/dev`
- [x] `pnpm format` — clean
- [x] `pnpm lint` — 3 pre-existing `<img>` warnings on files I didn't
touch, no errors
- [x] `pnpm types` — pre-existing errors on `AgentActivityDropdown` that
also fail on `origin/dev` (unrelated to this PR; needs a separate fix on
dev)
- [x] Live repro on dev verified Bug 2 fires against current prod code —
two fresh Sentry events in `AUTOGPT-SERVER-6HB` at 2026-04-21T21:35:54Z
on `app:dev-behave:cloud` matching the exact `DELETE
/api/integrations/google/credentials/{cred_id}` path. Airtable OAuth2
delete as a control worked cleanly, confirming Google-specific.
- [x] Live repro on dev verified Bug 4 (CoPilot direct-run variant) —
`{"spreadsheet": {"id": "..."}}` → `Cannot use file 'None' (type: None)`
from `_validate_spreadsheet_file` mimeType check, as expected.

Reviewer post-merge verification:
- [ ] Delete a Google OAuth credential via the Integrations UI —
succeeds cleanly, no Sentry event fires
- [ ] Connect Google twice (same account, same scopes) — credential
count stays at 1 (dedup)
- [ ] Save an agent graph with
`GoogleSheetsReadBlock.constantInput.spreadsheet = "bare-id"` via API —
graph validator rejects with `AgentGoogleDriveFileInputBlock`
remediation
- [ ] Save an agent graph with `GoogleSheetsReadBlock` whose
`spreadsheet` is fed by an upstream
`AgentGoogleDriveFileInputBlock.result` — validator accepts, agent runs

### Out of scope (for follow-ups)

- **Bug 1 — "Failed to retrieve Google OAuth credentials"** in
`frontend/src/components/contextual/GoogleDrivePicker/useGoogleDrivePicker.ts:163`.
Zero hits for this string in the beta user's Langfuse traces and we
weren't able to reproduce it from a clean flow. Most likely a
stale-credential race condition (delete in another tab, picker queries a
stale React-Query cache). Tracked as a separate task; not blocking.
- **CoPilot first-attempt mimeType retry loop.** Observed on dev:
CoPilot's first call to `GoogleSheetsReadBlock` sends `{"spreadsheet":
{"id": "..."}}` without `mimeType`, hits `_validate_spreadsheet_file`,
retries with mimeType. Costs a round-trip. Two possible fixes (relax
`_validate_spreadsheet_file` to skip when mimeType is `None` and let
Google's API surface the real error; OR extend
`get_auto_credentials_fields` metadata so CoPilot's tool description
prompts it to always include mimeType). Deliberately deferred — fixing
only one of "API caller sends a bare string" or "CoPilot sends an
incomplete object" risked the same auth-ambiguity the bare-string commit
in this branch history hit.
- **CoPilot agent-builder prompt/guide update.** The validator here
produces the correct error message, but the agent-builder model still
needs to learn to use `AgentGoogleDriveFileInputBlock` upfront rather
than discover it through validator retries. Separate handoff ticket
filed.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Medium Risk**
> Touches OAuth credential issuance/upgrade paths and introduces a new
endpoint that returns raw access tokens (scope-gated), plus broad
changes to execution-time credential resolution/validation; mistakes
could impact auth/security or break integrations.
> 
> **Overview**
> Fixes several Google/Drive agent-builder blockers by **supporting
incremental OAuth scope upgrades** and by hardening how
credential-bearing file inputs (“auto-credentials”) are validated,
resolved, and cleared on graph fork.
> 
> On the integrations API, `/{provider}/login` now accepts
`credential_id` and persists it in `OAuthState` to upgrade an existing
OAuth2 credential on callback (explicit upgrade), with an implicit merge
path for same `provider+username`. The callback path now merges
scopes/metadata, preserves ID/title, preserves existing
`refresh_token`/`username` when missing from incremental responses,
blocks upgrades for managed/system credentials, and adds a **new
`/{provider}/credentials/{cred_id}/picker-token` endpoint** to return a
short-lived access token for provider-hosted pickers (currently
allowlisted to Google Drive scopes).
> 
> For auto-credentials, `CredentialsFieldInfo` gains
`is_auto_credential` + `input_field_name`, graphs now expose
`regular_credentials_inputs` vs `auto_credentials_inputs`, and multiple
callers switch from `aggregate_credentials_inputs()` to
`regular_credentials_inputs` so embedded picker credentials aren’t
treated as user-mapped inputs. Execution-time auto-credential
acquisition is extracted into `_acquire_auto_credentials()` with clearer
error handling and lock cleanup; block execution adds a systemic guard
to surface a clean `Missing credentials` error when auto-credentials are
absent.
> 
> Separately fixes Google credential deletion by rewriting
`GoogleOAuthHandler.revoke_tokens()` to use the platform `Requests`
helper (bounded retries) instead of `AuthorizedSession`, and expands
test coverage across these flows (incremental OAuth, picker-token,
auto-credential validation/acquisition, graph validator, and frontend
diagnostics test stubs).
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
cac36ea. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

conflicts Automatically applied to PRs with merge conflicts platform/backend AutoGPT Platform - Back end platform/blocks platform/frontend AutoGPT Platform - Front end size/xl

Projects

Status: ✅ Done
Status: Done

Development

Successfully merging this pull request may close these issues.

5 participants