broaden default Quay OAuth scopes#310
Conversation
Adds user:admin and org:admin to the default scopes. oauth_setup.yaml now skips org/app creation when quay-oauth-credentials already exists and only regenerates the token when scopes drift. A quay-oauth-sync tag in 06-day2.yaml covers existing clusters.
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
✅ Files skipped from review due to trivial changes (1)
WalkthroughOAuth scopes for Quay are expanded to include user and organization admin permissions. A new documentation file provides a runbook for regenerating Quay OAuth access tokens after scope changes, including prerequisites, script steps, and verification procedures. Changes
Estimated code review effort🎯 1 (Trivial) | ⏱️ ~5 minutes 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
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. Review rate limit: 0/1 reviews remaining, refill in 60 minutes.Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
playbooks/06-day2.yaml (1)
86-94: Consider making OAuth sync explicitly opt-in for Day-2 runs.Lines 86-94 add a mutating credential/scope reconciliation step to the default Day-2 flow. Given the blast radius, a standalone playbook (or an extra opt-in var) would make operational intent clearer while keeping
--tags quay-oauth-syncfor targeted runs.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@playbooks/06-day2.yaml` around lines 86 - 94, The new "Sync Quay OAuth credentials with desired scopes" task currently runs by default when quayOAuthApp.enabled is true; change it to be explicit opt‑in by adding an additional condition or variable (e.g., quayOAuthSyncEnabled default false) and update the task's when to require both quayOAuthApp.enabled and quayOAuthSyncEnabled, or extract the include_tasks (../operators/quay-operator/oauth_setup.yaml) into a separate standalone playbook that operators run intentionally; preserve the existing tag quay-oauth-sync so targeted runs still work.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@operators/quay-operator/oauth_setup.yaml`:
- Around line 27-33: The current set_fact uses direct indexing into
r_quay_oauth_secret_existing.resources[0].data which will error if the Secret is
present but missing keys; change those to safe lookups (e.g., use the dict .get
method or |default fallbacks) when assigning quay_oauth_client_id,
quay_oauth_client_secret, and quay_oauth_current_scopes so missing keys yield
empty strings rather than raising (for example:
r_quay_oauth_secret_existing.resources[0].data.get('client-id','') | b64decode
or r_quay_oauth_secret_existing.resources[0].data.get('scopes','') | default('')
| b64decode), keeping the quay_oauth_secret_exists guard unchanged.
---
Nitpick comments:
In `@playbooks/06-day2.yaml`:
- Around line 86-94: The new "Sync Quay OAuth credentials with desired scopes"
task currently runs by default when quayOAuthApp.enabled is true; change it to
be explicit opt‑in by adding an additional condition or variable (e.g.,
quayOAuthSyncEnabled default false) and update the task's when to require both
quayOAuthApp.enabled and quayOAuthSyncEnabled, or extract the include_tasks
(../operators/quay-operator/oauth_setup.yaml) into a separate standalone
playbook that operators run intentionally; preserve the existing tag
quay-oauth-sync so targeted runs still work.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: c1ee4e63-ba29-4d9d-9503-5a7e4f72aec8
📒 Files selected for processing (3)
defaults/quay_operator.yamloperators/quay-operator/oauth_setup.yamlplaybooks/06-day2.yaml
| - name: Reuse credentials from existing Secret | ||
| no_log: true | ||
| when: quay_oauth_secret_exists | ||
| ansible.builtin.set_fact: | ||
| quay_oauth_client_id: "{{ r_quay_oauth_secret_existing.resources[0].data['client-id'] | b64decode }}" | ||
| quay_oauth_client_secret: "{{ r_quay_oauth_secret_existing.resources[0].data['client-secret'] | b64decode }}" | ||
| quay_oauth_current_scopes: "{{ r_quay_oauth_secret_existing.resources[0].data['scopes'] | default('') | b64decode }}" |
There was a problem hiding this comment.
Handle incomplete existing OAuth Secrets defensively.
At Line 31 and Line 32, direct key indexing (data['client-id'], data['client-secret']) will fail hard if the Secret exists but is incomplete. This blocks recovery paths during upgrades/drift scenarios.
Suggested hardening
- name: Reuse credentials from existing Secret
no_log: true
when: quay_oauth_secret_exists
ansible.builtin.set_fact:
- quay_oauth_client_id: "{{ r_quay_oauth_secret_existing.resources[0].data['client-id'] | b64decode }}"
- quay_oauth_client_secret: "{{ r_quay_oauth_secret_existing.resources[0].data['client-secret'] | b64decode }}"
- quay_oauth_current_scopes: "{{ r_quay_oauth_secret_existing.resources[0].data['scopes'] | default('') | b64decode }}"
+ quay_oauth_client_id: "{{ (r_quay_oauth_secret_existing.resources[0].data | default({})).get('client-id', '') | b64decode }}"
+ quay_oauth_client_secret: "{{ (r_quay_oauth_secret_existing.resources[0].data | default({})).get('client-secret', '') | b64decode }}"
+ quay_oauth_current_scopes: "{{ (r_quay_oauth_secret_existing.resources[0].data | default({})).get('scopes', '') | b64decode }}"🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@operators/quay-operator/oauth_setup.yaml` around lines 27 - 33, The current
set_fact uses direct indexing into
r_quay_oauth_secret_existing.resources[0].data which will error if the Secret is
present but missing keys; change those to safe lookups (e.g., use the dict .get
method or |default fallbacks) when assigning quay_oauth_client_id,
quay_oauth_client_secret, and quay_oauth_current_scopes so missing keys yield
empty strings rather than raising (for example:
r_quay_oauth_secret_existing.resources[0].data.get('client-id','') | b64decode
or r_quay_oauth_secret_existing.resources[0].data.get('scopes','') | default('')
| b64decode), keeping the quay_oauth_secret_exists guard unchanged.
|
/ok-to-test |
There was a problem hiding this comment.
this PR introduces a configuration change together with somewhat of a migration to put it in place.
not sure this is a desired pattern at this point.
i suggest to submit the configuration change only (together with a document perhaps). generally speaking, i think quay-oauth would be a nice plugin (as in, extract this entire functionality to a plugin).
| when: | ||
| - quay_oauth_client_id is defined | ||
| - quay_oauth_client_id | length > 0 | ||
| - not quay_oauth_secret_exists or (quay_oauth_current_scopes.split() | sort) != (quayOAuthApp.scopes.split() | sort) |
There was a problem hiding this comment.
what happens to current token if scopes have changed?
There was a problem hiding this comment.
It will remain in Quay. I haven't found a reliable way to revoke it via automation, so I'll document how to revoke it manually via UI.
|
is the oauth token only available to MSP admin users, and NOT accessible to tenant? |
Yes, it is only available to MSP admins. |
Good idea. I've updated the PR to include only the config and doc on how to reissue the token on live clusters. |
Description
Adds
user:adminandorg:adminto the default scopes.oauth_setup.yamlskips org/app creation whenquay-oauth-credentialsexists and regenerates the token only when scopes drift.quay-oauth-synctag in06-day2.yamlcovers existing clusters.Open question
06-day2.yamlthe right place to add sync for upgrading existing clusters or should it live in a standalone playbook?Testing:
Summary by CodeRabbit
New Features
Documentation