Skip to content

Add revoke action and YAML support for permission updates#1461

Open
anniegracehu wants to merge 18 commits intocloud-ark:masterfrom
anniegracehu:annie/revoke-update-perm-yaml-json
Open

Add revoke action and YAML support for permission updates#1461
anniegracehu wants to merge 18 commits intocloud-ark:masterfrom
anniegracehu:annie/revoke-update-perm-yaml-json

Conversation

@anniegracehu
Copy link
Copy Markdown
Collaborator

@anniegracehu anniegracehu commented Mar 30, 2026

Summary

  • add revoke action to provider-kubeconfig.py
  • support both JSON and YAML permission files for update and revoke
  • keep <sa>-perms configmap synchronized when updating and revoking permissions
  • add tests for revoke CLI validation and permission file parsing
  • add manual YAML fixture for update/revoke e2e at tests/manual/update-revoke-perms.yaml

Test plan

  • python3 -m unittest tests/test_provider_kubeconfig.py

Manual update/revoke e2e (existing SA)

Use an existing service account (example: argocd-application-controller in argocd) and verify update/revoke without creating a new SA.

# Inputs
NS=default
SA=default
KCFG="$HOME/.kube/config"
PERMS=tests/manual/update-revoke-perms.yaml

# 1) Baseline (expected: no)
kubectl auth can-i create secrets -n "$NS" --as=system:serviceaccount:$NS:$SA --kubeconfig="$KCFG"

# 2) Grant via update (expected: yes)
python3 provider-kubeconfig.py update "$NS" -c "$SA" -p "$PERMS" -k "$KCFG"
kubectl auth can-i create secrets -n "$NS" --as=system:serviceaccount:$NS:$SA --kubeconfig="$KCFG"

# 3) Revoke (expected: no)
python3 provider-kubeconfig.py revoke "$NS" -c "$SA" -p "$PERMS" -k "$KCFG"
kubectl auth can-i create secrets -n "$NS" --as=system:serviceaccount:$NS:$SA --kubeconfig="$KCFG"

Support permission updates and revocations from both JSON and YAML files, reuse shared parsing/configmap helpers, and extend tests to cover revoke CLI validation and multi-format permission file parsing.

Made-with: Cursor
@anniegracehu anniegracehu force-pushed the annie/revoke-update-perm-yaml-json branch from 5e4ab35 to 6e0c42b Compare March 30, 2026 18:23
Run new update parser in shadow mode behind an env flag and assert old/new parity, with tests validating parser output equivalence.

Made-with: Cursor
Inline legacy update parsing in _update_rbac for source-of-truth behavior and keep old/new parity assertions behind KUBEPLUS_UPDATE_EQ_CHECK, while removing extra helper methods.

Made-with: Cursor
Use _load_permission_data only in _update_rbac and keep the original rule loop. Drop dual-parser parity and its test. Match _parse_permission_rules to legacy by always appending rule_group. Return early from revoke when no update ClusterRole exists to avoid rewriting perms configmap.

Made-with: Cursor
@anniegracehu anniegracehu self-assigned this Mar 30, 2026
Add _parse_update_rules_legacy for a single legacy implementation, optional KUBEPLUS_UPDATE_EQ_CHECK assertion against _parse_permission_rules in _update_rbac, and a unit test including non-apigroup edge cases.

Made-with: Cursor
Remove duplicate _parse_update_rules_legacy and env parity self-check; add a focused test for non-apigroup edge case.

Made-with: Cursor
Provide a minimal permissions file to validate update/revoke against an existing service account during manual testing.

Made-with: Cursor
Provide three paired examples under tests/permission_files to validate update/revoke behavior with auth can-i for both input formats.

Made-with: Cursor
Parse all JSON and YAML fixtures in tests/permission_files through provider-kubeconfig helpers to validate real file-based inputs used in manual update/revoke checks.

Made-with: Cursor
Use tests/permission_files fixtures for manual checks and test coverage instead of the old tests/manual file.

Made-with: Cursor
Verify update/revoke using matching JSON and YAML permission fixtures produce the same auth can-i transition on an existing service account (deny -> allow -> deny).

Made-with: Cursor
Use standard '' key notation instead of explicit ? mapping form for readability while preserving equivalent fixture semantics.

Made-with: Cursor
Prefer <sa>-update for revoke, then fall back to <sa> if needed; keep perms configmap sync and add integration coverage. Normalize permission fixtures so JSON/YAML stay equivalent and single-key per rule entry.

Made-with: Cursor
Replace explicit '? ""' mapping form with standard '' key notation for readability and consistency.

Made-with: Cursor
Copy link
Copy Markdown
Contributor

@devdattakulkarni devdattakulkarni left a comment

Choose a reason for hiding this comment

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

Added some comments.

Comment thread provider-kubeconfig.py
if resource not in resources:
resources.append(resource.strip())
rule_group = {}
if api_group == "non-apigroup":
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.

This is present in the old permission file.

- get
- update
- patch
configmaps/resourceName::cert-manager-cainjector-leader-election-core:
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.

This should be -configmaps/resourceName::

Comment thread provider-kubeconfig.py Outdated
revoke_rule_list, revoke_resources = self._parse_permission_rules(perms)
revoke_norm = set(tuple(sorted(r.items())) for r in self._normalize_rule_list(revoke_rule_list))

role_name = sa + "-update"
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.

Here we are assuming that the role name (sa-"update") already exists on the cluster.

Comment thread provider-kubeconfig.py Outdated
remaining_rules = []
for rule in existing_rules:
norm = self._normalize_rule(rule)
norm_key = tuple(sorted(norm.items()))
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.

Could we add a small example in comment. What would be norm_key and what would be the rule.

Comment thread provider-kubeconfig.py Outdated
)
def _revoke_rbac(self, permissionfile, sa, namespace, kubeconfig):
"""Revoke permissions from JSON/YAML file for provider/consumer update role."""
perms = self._load_permission_data(permissionfile)
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.

Suppose originally the SA has following perms:

  • ""
    pod:
    • get, delete

Suppose permissionfile has the following:

  • ""
    pod:
    • delete

After revoke, we want the SA to have the following perms:

  • ""
    pod:
    • get

Comment thread provider-kubeconfig.py Outdated
norm = self._normalize_rule(rule)
norm_key = tuple(sorted(norm.items()))
if norm_key not in revoke_norm:
remaining_rules.append(rule)
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.

Iterate through the existing rules on the SA. If the rule does not exist in the revoke_norm then add it to the remaining rules.

Handle null rules safely, only fall back to base role on NotFound, apply minimal role objects during revoke updates, and use system temp files in tests while validating verb-level revoke behavior.

Made-with: Cursor
Fix NotFound fallback checks, preserve labels/annotations on role rewrite, handle null rules safely, keep configmap resources when scope/verbs remain, and add integration coverage for multi-resource and wildcard revoke behavior.

Made-with: Cursor
Consolidate follow-up bug fixes into a single, readable revoke path that preserves intended RBAC semantics (including nonResourceURL matching, base-role fallback, and scoped multi-resource revocation) while trimming test complexity to focused behavior coverage.
@anniegracehu anniegracehu force-pushed the annie/revoke-update-perm-yaml-json branch from 948d3d2 to 9475a4b Compare April 16, 2026 05:21
Restructure revoke logic for readability with plain-language scope comments, inline flow-oriented rule rewriting, and reduced helper complexity while keeping documented revoke behavior and test coverage aligned.

Made-with: Cursor
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.

2 participants