Skip to content

fix: block normal users from viewing secret dataset API keys#28515

Open
honjo-hiroaki-gtt wants to merge 10 commits intolanggenius:mainfrom
honjo-hiroaki-gtt:feature/restrict-dataset-apikey-visibility
Open

fix: block normal users from viewing secret dataset API keys#28515
honjo-hiroaki-gtt wants to merge 10 commits intolanggenius:mainfrom
honjo-hiroaki-gtt:feature/restrict-dataset-apikey-visibility

Conversation

@honjo-hiroaki-gtt
Copy link

Summary

  • block normal/viewer roles from fetching or seeing dataset secret API keys (403 on backend)
  • allow only workspace editors or dataset operators to view/generate dataset API keys; other API key flows unchanged
  • align UI by hiding the “API Key” button and modal unless the user meets those roles

Fixes #28514.

Screenshots

Before After
CleanShot 2025-11-21 at 19 17 23@2x CleanShot 2025-11-21 at 19 25 24@2x

Checklist

  • This change requires a documentation update, included: Dify Document
  • I understand that this PR may be closed in case there was no previous discussion or issues. (This doesn't apply to typos!)
  • I've added a test for each change that was introduced, and I tried as much as possible to make a single atomic change.
  • I've updated the documentation accordingly.
  • I ran dev/reformat(backend) and cd web && npx lint-staged(frontend) to appease the lint gods

@dosubot dosubot bot added the size:M This PR changes 30-99 lines, ignoring generated files. label Nov 21, 2025
@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello @honjo-hiroaki-gtt, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request significantly enhances security by implementing robust access control for secret API keys. It introduces both backend and frontend changes to ensure that only authorized users (specifically workspace editors or dataset operators for dataset API keys, and workspace editors for general secret keys) can view or generate these sensitive credentials. This prevents normal users or viewers from accessing API key information, thereby aligning the user interface with the new, stricter access policies.

Highlights

  • Backend API Key Access Control: Implemented a backend check to restrict access to dataset secret API keys, allowing only workspace editors or dataset operators to view or generate them. Any unauthorized attempt will result in a 403 Forbidden error.
  • Frontend UI Alignment for Dataset API Keys: The 'API Key' button and its associated modal for datasets are now conditionally rendered, appearing only for users with editor or dataset operator roles, aligning the UI with backend permissions.
  • Frontend UI Alignment for General Secret Keys: The general 'Secret Key' button is now hidden for users who are not workspace editors, further enhancing security by restricting visibility of sensitive features.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Contributor

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

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 adds permission checks for viewing API keys, a crucial security enhancement. For datasets, it restricts access to editors and dataset operators, while for other resources like apps, it limits access to editors. The UI is updated accordingly to hide API key management from unauthorized users. The implementation is mostly correct, but I've found a critical security vulnerability: the new permission checks only apply to listing keys (GET), while creating (POST) and deleting (DELETE) keys seem to be unprotected. I've also added a suggestion to improve the code's readability.

honjo-hiroaki-gtt and others added 3 commits November 21, 2025 21:36
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
…taset-apikey-visibility

# Conflicts:
#	api/controllers/console/apikey.py
@asukaminato0721
Copy link
Contributor

/gemini review

Copy link
Contributor

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

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 effectively addresses the security concern of unauthorized access to dataset API keys. The backend changes correctly implement role-based access control for API key operations, ensuring that only users with appropriate permissions can view, create, or delete them. The frontend changes align with this by conditionally rendering the UI elements related to API key management, which improves the user experience by not showing options that are not available to them. The implementation is solid and follows best practices. I have one suggestion to improve the naming of a variable in the frontend for better code clarity and maintainability.

const [isSecretKeyModalVisible, setIsSecretKeyModalVisible] = useState(false)

const isCurrentWorkspaceManager = useAppContextSelector(state => state.isCurrentWorkspaceManager)
const isDatasetApiKeyVisible = useAppContextSelector(state => state.isCurrentWorkspaceEditor || state.isCurrentWorkspaceDatasetOperator)
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

For better code clarity and maintainability, consider renaming isDatasetApiKeyVisible to something that more accurately reflects the permission being checked, such as canManageDatasetApiKeys. This name aligns better with the concept of checking a user's role for managing API keys, rather than just controlling UI visibility. You would need to update its usages in this file as well.

Additionally, the logic state.isCurrentWorkspaceEditor || state.isCurrentWorkspaceDatasetOperator is equivalent to the backend's is_dataset_editor permission. It would be ideal to encapsulate this logic within the AppContext as a single selector, for example isCurrentWorkspaceDatasetEditor, to promote reusability and keep permission logic centralized.

Suggested change
const isDatasetApiKeyVisible = useAppContextSelector(state => state.isCurrentWorkspaceEditor || state.isCurrentWorkspaceDatasetOperator)
const canManageDatasetApiKeys = useAppContextSelector(state => state.isCurrentWorkspaceEditor || state.isCurrentWorkspaceDatasetOperator)

Copy link
Author

Choose a reason for hiding this comment

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

@gemini-code-assist
Thanks for the feedback! I’ve renamed the variable to canManageDatasetApiKeys and added the centralized selector isCurrentWorkspaceDatasetEditor in AppContext to align the permission check. Changes are pushed—could you take another look?

/gemini review

@honjo-hiroaki-gtt
Copy link
Author

/gemini review

Copy link
Contributor

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

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 effectively restricts access to dataset API keys for users with normal/viewer roles, both on the backend and frontend. The changes are well-aligned with the goal of enhancing security. The backend logic correctly enforces permissions for creating, viewing, and deleting API keys based on user roles and resource type. The frontend conditionally renders UI elements for API key management, providing a consistent user experience.

I've included a couple of suggestions to improve code maintainability and readability. One is to refactor a new permission flag in the React context to be more declarative and avoid repeating logic. The other points out some code duplication in the Python backend's new permission-checking methods, which could be consolidated to prevent potential inconsistencies in the future.

Comment on lines +117 to +120
def _has_permission(self, user):
if self.resource_type == "dataset":
return user.is_dataset_editor
return user.is_admin_or_owner
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

This _has_permission method is very similar to the one in BaseApiKeyListResource on line 55. This duplication could lead to maintenance issues in the future (e.g., if permission logic for datasets changes, it would need to be updated in two places). Consider refactoring to a shared utility function to centralize the permission logic.

Copy link
Author

Choose a reason for hiding this comment

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

@gemini-code-assist
Thanks for the suggestion! I’ve centralized the dataset permission check into _has_dataset_permission and now both BaseApiKeyListResource and BaseApiKeyResource call it, removing the duplicated logic. Changes are pushed. Please take another look.

Copy link
Contributor

Choose a reason for hiding this comment

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

That's an excellent solution! Centralizing the _has_dataset_permission function and having both BaseApiKeyListResource and BaseApiKeyResource utilize it effectively removes the duplication and improves maintainability, as suggested. The changes look good.

honjo-hiroaki-gtt and others added 2 commits November 23, 2025 11:30
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
@honjo-hiroaki-gtt
Copy link
Author

/gemini review

Copy link
Contributor

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

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 aims to restrict access to dataset API keys. The backend changes in api/controllers/console/apikey.py introduce a new permission model for API key access, which is a good step towards centralized authorization logic. The frontend changes in web/app/components/datasets/extra-info/service-api/card.tsx and web/context/app-context.tsx correctly implement the UI restrictions for dataset API keys.

However, I've found a couple of issues where the changes also affect API key flows for applications, which contradicts the PR description's statement that 'other API key flows [are] unchanged'. My review includes suggestions to address these inconsistencies. Please review them and clarify the intended scope of this PR.

Comment on lines +70 to +71
if not self._has_permission(current_user):
raise Forbidden()
Copy link
Contributor

Choose a reason for hiding this comment

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

high

This permission check introduces a new restriction on listing API keys for non-dataset resources (e.g., apps), requiring edit permissions where none were needed before. This contradicts the PR's goal of leaving 'other API key flows unchanged'.

For the get method, the permission check should only apply to datasets to maintain existing behavior for other resources.

Suggested change
if not self._has_permission(current_user):
raise Forbidden()
if self.resource_type == "dataset" and not _has_dataset_permission(current_user):
raise Forbidden()

Copy link
Author

Choose a reason for hiding this comment

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

@gemini-code-assist
Thanks for catching that. I reverted the new restriction so the GET permission check now applies only to datasets and leaves other resources unchanged. Changes are pushed. Please recheck.

Copy link
Contributor

Choose a reason for hiding this comment

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

Thank you for the update! I've reviewed the changes in api/controllers/console/apikey.py, and the permission check for the get method now correctly applies only to datasets, aligning with the original behavior for other resources. This resolves the issue. Well done!

Comment on lines +20 to +21
if (!isCurrentWorkspaceEditor)
return null
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

This change restricts access to app API keys to workspace editors. This is a change to the app API key flow, which the PR description states should be 'unchanged'. If this change is intended, the PR description should be updated to reflect the expanded scope. Otherwise, this check should be removed to preserve the existing behavior for app API keys.

Copy link
Author

Choose a reason for hiding this comment

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

@gemini-code-assist
Good point. I removed the workspace-editor gate from the app secret key button to preserve the previous app API key flow. Updated code is pushed. Please take another look.

Copy link
Contributor

Choose a reason for hiding this comment

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

Thanks for confirming the fix, @honjo-hiroaki-gtt. I've reviewed the updated code and it looks good.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:M This PR changes 30-99 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

App secret keys are visible to normal users

2 participants