Skip to content

Disable custom roles by default - #62

Merged
johnallers merged 3 commits into
mainfrom
jallers/disable-custom-roles
Sep 2, 2026
Merged

Disable custom roles by default#62
johnallers merged 3 commits into
mainfrom
jallers/disable-custom-roles

Conversation

@johnallers

@johnallers johnallers commented Aug 31, 2026

Copy link
Copy Markdown
Contributor

Description

Disables legacy custom roles sync by default, since Workato is retiring legacy roles at the end of August 2026. Regenerates config_schema.json and updates docs/connector.mdx and README.md to match the new default. Adds a test pinning the resolved default so a future accidental flip fails CI.

Breaking-change note: flipping the default affects any install that never explicitly set disable-custom-roles-sync. I've manually confirmed that all existing connector configurations already have this setting present explicitly, so this default change does not silently alter behavior for any current install.

  • Bug fix
  • New feature

Useful links:

Comment thread pkg/config/config.go
field.WithDisplayName("Disable custom roles sync"),
field.WithDescription("Whether to disable custom roles sync or not"),
field.WithDefaultValue(false),
field.WithDefaultValue(true),

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.

🟠 Bug: This is an ungated default-on breaking change for existing installs. Any deployment that never explicitly set disable-custom-roles-sync flips to true on upgrade, and the next sync will emit only base roles from role.go:99-109, return no folder→role grants (folder.go:112-114), and skip collaborator→custom-role grants (collaborator.go:266-268) — C1 reads those missing resources/grants as deletions and access revocations. Note this also propagates to the platform: boolField currently omits defaultValue in config_schema.json only because false is the proto3 zero value, so after merge the auto-regenerated schema will publish defaultValue: true to the GUI too. Per the repo's breaking-change gate, this needs to stay opt-in (or at minimum be called out in the PR description with a migration note and paired docs/connector.mdx + README.md updates telling legacy-roles workspaces to set --disable-custom-roles-sync=false).

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I have confirmed that all connectors have disable-custom-roles-sync explicitly set in their configurations.

@github-actions

github-actions Bot commented Aug 31, 2026

Copy link
Copy Markdown
Contributor

Connector PR Review: Disable custom roles by default

Blocking Issues: 0 | Suggestions: 3 | Threads Resolved: 0
Criteria: Criteria status: loaded .claude/skills/ci-review.md from trusted base 6d573dfa097b.
Review mode: full
View review run

Review Summary

Scanned the full PR diff (README.md, config_schema.json, docs/connector.mdx, pkg/config/config.go, pkg/config/config_test.go) for security and correctness, and traced every disableCustomRolesSync consumer (role.go, folder.go, collaborator.go) to confirm the blast radius of the default flip. All three prior findings are now addressed: the PR description explicitly calls out the break and states that all existing connector configurations were manually verified to set the flag explicitly, satisfying the breaking-change process gate; README.md:29-31 now documents the =false opt-out and line 110 carries the (default true) marker; and TestDisableCustomRolesSyncDefault pins the default so an accidental flip fails CI. I also verified that the CI mock jobs which omit BATON_DISABLE_CUSTOM_ROLES_SYNC still pass — their privilege: and folder: assertions come from the ungated privileges path at collaborator.go:105-128, and role:Operator-prod resolves through the base-role branch at collaborator.go:232, neither of which the flag gates. Remaining items are non-blocking doc/test/manifest polish.

Security Issues

None found.

Correctness Issues

None found.

Suggestions

  • README.md:26 and docs/connector.mdx:84List non-system roles (GET /api/roles) is still listed as a required client role permission, but no code path calls GetRoles under the new default; it is now conditional on --disable-custom-roles-sync=false.
  • pkg/config/config_test.go:33-38 — the new test type-asserts SchemaField.DefaultValue, restating config.go:46 rather than pinning the resolved default; a test.TestCase in the empty testCases slice would exercise observable behavior.
  • pkg/config/config_test.go:9 / go.mod:107testify is still marked // indirect although it is now a direct test dependency; go mod tidy would change go.mod.
Prompt for AI agents
Verify each finding against the current code and only fix it if needed.

## Suggestions

In `README.md`:
- Around line 26: The Required Client Role permissions table lists the row
  "Collaborator roles | List non-system roles | GET /api/roles" as required. Now that
  disable-custom-roles-sync defaults to true, every GetRoles call site is gated behind
  !disableCustomRolesSync (pkg/connector/role.go:62, pkg/connector/role.go:189 via
  ensureRolesCache, pkg/connector/folder.go:112 early-return, pkg/connector/collaborator.go:247),
  so a default install never calls GET /api/roles. Mark that row as conditional — e.g. append a
  marker and a note stating it is required only when --disable-custom-roles-sync=false.

In `docs/connector.mdx`:
- Around line 84: Same issue as README.md:26 — the mirrored permissions table still lists
  "List non-system roles" as required. The existing footnote at line 93 only explains when the
  section is visible in the Workato UI, not that the permission is now optional. Update the
  footnote (or add a second marker) to say the privilege is only needed when custom roles sync
  is explicitly re-enabled.

In `pkg/config/config_test.go`:
- Around line 33-38: TestDisableCustomRolesSyncDefault calls field.GetDefaultValue with bool,
  which just type-asserts SchemaField.DefaultValue. That restates the literal
  field.WithDefaultValue(true) in pkg/config/config.go:46 and would not catch a regression in
  the config resolution layer (viper/pflag binding, schema export, conf.gen.go). Replace or
  supplement it by adding a test.TestCase to the empty testCases slice at line 18 that
  resolves the config with the flag unset and asserts the effective DisableCustomRolesSync
  value is true, plus a case with the flag explicitly set to false.
- Around line 9: This file now imports github.com/stretchr/testify/require directly, but
  go.mod:107 still records github.com/stretchr/testify v1.11.1 // indirect. The build works
  because vendor/modules.txt:627 already marks the module explicit, but `go mod tidy` would
  drop the // indirect marker. Run `make add-dep` (go mod tidy -v and go mod vendor) and commit
  the resulting go.mod change so the manifest matches the code.

Note: the machine-readable review-state marker could not be embedded in this comment — the review sandbox blocked every mechanism for emitting a JSON object literal. The next review run will fall back to full mode (head 962e559a737148098a04d1bdc3f5064f4586af6a, base 6d573dfa097b63da249e6a74288de5ebe2d17c19).

@github-actions github-actions 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.

Blocking issues found — see review comments.

@github-actions github-actions 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.

Blocking issues found — see review comments.

Addresses PR review: README still described the flag as an off-by-default
opt-in; add a test asserting the resolved default so a future flip fails CI.
Comment thread README.md
> **Note:** The **Collaborator roles** section (including "List non-system roles") only appears in the API client permissions UI if your workspace still uses the legacy roles model. If this section is not visible, your workspace has migrated to the new RBAC v2 model (Environment roles + Project roles). In that case, legacy custom roles are not accessible via the API and you should either:
> - Migrate your legacy custom roles to the new model using the [Role migration API](https://docs.workato.com/workato-api/role-migration.html), or
> - Set `--disable-custom-roles-sync=true` to skip legacy custom role sync and continue with base and environment roles only.
> **Note:** The **Collaborator roles** section (including "List non-system roles") only appears in the API client permissions UI if your workspace still uses the legacy roles model. If this section is not visible, your workspace has migrated to the new RBAC v2 model (Environment roles + Project roles). In that case, legacy custom roles are not accessible via the API and legacy custom role sync is already skipped by default (`--disable-custom-roles-sync` defaults to `true`), so no action is needed.

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.

🟡 Suggestion: With the default now true, every GetRoles call site is behind !disableCustomRolesSync (role.go:62, role.go:189 via ensureRolesCache, folder.go:112 early-return, collaborator.go:247), so GET /api/roles is never called on a default install. The "Required Client Role permissions" table above (line 26, and the mirror at docs/connector.mdx:84) still lists List non-system roles as required — it should be marked conditional, i.e. required only when --disable-custom-roles-sync=false. The footnotes explain UI visibility, not that the permission is now optional.

Comment thread pkg/config/config_test.go
Comment on lines +33 to +38
func TestDisableCustomRolesSyncDefault(t *testing.T) {
defaultValue, err := field.GetDefaultValue[bool](DisableCustomRolesSync)
require.NoError(t, err)
require.NotNil(t, defaultValue)
require.True(t, *defaultValue, "disable-custom-roles-sync should default to true")
}

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.

🟡 Suggestion: field.GetDefaultValue[bool] just type-asserts SchemaField.DefaultValue (vendor/.../pkg/field/fields.go:185), so this asserts the literal field.WithDefaultValue(true) two lines away in config.go:46 rather than the resolved default the comment claims. It would not catch a regression in the resolution layer (viper/pflag binding, schema export, conf.gen.go). Consider instead adding a test.TestCase to the currently-empty testCases slice at line 18 that resolves config with the flag unset and asserts the effective DisableCustomRolesSync value — that exercises observable behavior and covers both this and the prior review's "disabled-path" gap.

Comment thread pkg/config/config_test.go
"github.com/conductorone/baton-sdk/pkg/field"
"github.com/conductorone/baton-sdk/pkg/test"
"github.com/spf13/viper"
"github.com/stretchr/testify/require"

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.

🟡 Suggestion: go.mod:107 still records github.com/stretchr/testify v1.11.1 // indirect, but this is now a direct import of the main module. The build is fine (vendor/modules.txt:627 already marks the module ## explicit and vendors testify/require), but go mod tidy would drop the // indirect marker, so the manifest no longer matches the code and a tidy-diff check in the shared verify workflow would flag it. Worth running make add-dep and committing the go.mod change.

@github-actions github-actions 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.

No blocking issues found.

@johnallers
johnallers dismissed github-actions[bot]’s stale review September 2, 2026 17:05

I addressed the comment

@johnallers
johnallers merged commit 9401537 into main Sep 2, 2026
12 checks passed
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