Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
51 commits
Select commit Hold shift + click to select a range
d950095
feat: add clm_workflow_queue resource type (Pylon #11836)
FeliLucero1 Aug 10, 2026
2ede60c
fix: address deep-code-review findings on clm_workflow_queue
FeliLucero1 Aug 10, 2026
3319a9c
fix: address current bot review findings on PR #67
FeliLucero1 Aug 10, 2026
39745ec
fix: address incremental bot review findings on PR #67
FeliLucero1 Aug 10, 2026
3efcf69
fix: don't discard already-discovered queues on a later member's failure
FeliLucero1 Aug 10, 2026
4cd2db2
fix: gate escalation on a member ever succeeding, not on membership size
FeliLucero1 Aug 10, 2026
58c44e2
fix: escalate NotFound too when nothing has succeeded yet
FeliLucero1 Aug 11, 2026
d41585d
fix: require consecutive failures before escalating to account-unavai…
FeliLucero1 Aug 11, 2026
0f34430
doc: fix typo and stale sentinel doc after the consecutive-threshold fix
FeliLucero1 Aug 11, 2026
9192224
fix: log the below-threshold member skip, matching the post-success one
FeliLucero1 Aug 11, 2026
afac0cc
refactor: chunk clm_workflow_queue's member scan across List() calls
FeliLucero1 Aug 11, 2026
0c3c19e
fix: session-store-write-failure logs to Debug, not Warn
FeliLucero1 Aug 11, 2026
d19d711
fix: drop inaccurate justification in Debug-log comment
FeliLucero1 Aug 11, 2026
b6f7c83
fix: drop ticket/review-process references from code comments
FeliLucero1 Aug 11, 2026
df9bfbf
fix: address remaining review findings on clm_workflow_queue
FeliLucero1 Aug 11, 2026
426f5f9
fix: satisfy gocritic appendAssign on the membership merge
FeliLucero1 Aug 11, 2026
d1058d0
doc: drop internal ticket reference from README
FeliLucero1 Aug 12, 2026
bf91ba6
doc: fix stranded sentence in README after ticket-reference removal
FeliLucero1 Aug 12, 2026
cc23ac1
fix: dedup member merge against a resumed sync's replayed chunk
FeliLucero1 Aug 12, 2026
96d31b6
fix: don't double-count escalation counters on a replayed chunk
FeliLucero1 Aug 12, 2026
fb44dbc
fix: track the expected next input token instead of the last applied one
FeliLucero1 Aug 12, 2026
6afb2a1
fix: detect replay of a scan that completed in a single page
FeliLucero1 Aug 12, 2026
d0b92ed
fix: fail loudly instead of skipping gracefully when clm_workflow_que…
FeliLucero1 Aug 13, 2026
6c147ce
fix: restore CI coverage for the 5 still-tolerant CLM types, fix doc …
FeliLucero1 Aug 13, 2026
95c05ac
fix: guard against an empty member Href, fix stale test cross-references
FeliLucero1 Aug 13, 2026
78b175b
fix: give the empty-memberID skip its own counter, drop email from it…
FeliLucero1 Aug 13, 2026
98aac01
fix: Debug instead of Warn for skip-and-continue logs; propagate sess…
FeliLucero1 Aug 20, 2026
b61b45d
fix: include clm_workflow_queue in includeClm scope gating, describe …
FeliLucero1 Aug 20, 2026
f490a9a
fix: correct CLM resource-type count in isOptInFeatureUnavailableErro…
FeliLucero1 Aug 20, 2026
0776ee0
fix: use pageToken (not SucceededAtLeastOnce) to gate fail-loud on se…
FeliLucero1 Aug 20, 2026
6b36162
fix: correct 5-of-6 wording -- all 6 CLM types register unconditionally
FeliLucero1 Aug 20, 2026
0a2afb6
fix: correct helper.go doc -- only 4 CLM types tolerate this error, n…
FeliLucero1 Aug 20, 2026
52ff742
fix: correct ci.yaml comment count, add regression test for the false…
FeliLucero1 Aug 20, 2026
db761c0
fix: wrap test failure message to satisfy revive line-length-limit
FeliLucero1 Aug 20, 2026
3175d6d
fix: use pageToken (not SucceededAtLeastOnce) for the 4th session-sto…
FeliLucero1 Aug 20, 2026
5df561e
test: add membership-write hard-fail coverage after first chunk
FeliLucero1 Aug 20, 2026
3781191
fix: fail loud when discovery state is missing mid-scan (found == false)
FeliLucero1 Aug 20, 2026
0b435e0
test: add coverage for discovery state missing mid-scan (found == false)
FeliLucero1 Aug 20, 2026
3a9cb16
fix: document operator recovery for the found==false guard
FeliLucero1 Aug 20, 2026
0c00119
test: pin the found==false regression test to its specific error text
FeliLucero1 Aug 20, 2026
a956a1c
docs: trim workflow-queue comments and ship capabilities entry
FeliLucero1 Aug 21, 2026
2799c6d
docs: restore workflow-queue "why" after builder-doc trim
FeliLucero1 Aug 21, 2026
8ed5f36
Merge remote-tracking branch 'origin/main' into clm-workflow-queue-su…
FeliLucero1 Aug 26, 2026
cf14846
refactor: model clm_workflow_queue as ChildResourceType of clm_member
FeliLucero1 Aug 26, 2026
a73fbae
fix: gate clm_member grants on workflow queue opt-in
FeliLucero1 Aug 26, 2026
60f713f
refactor: drop unused parent param from parseIntoClmWorkflowQueueReso…
FeliLucero1 Aug 26, 2026
78f6808
test: pin includeClm and includeWorkflowQueues derivation in New()
FeliLucero1 Aug 26, 2026
9012d60
fix: no-op unparented List for child-only clm_workflow_queue
FeliLucero1 Aug 26, 2026
98a20f2
fix: address Sergio review nits on workflow queue sync
FeliLucero1 Aug 26, 2026
ab49815
fix: use Debug log for clm_workflow_queue without clm_member
FeliLucero1 Aug 26, 2026
e0f316e
fix: address open review items on clm_member and CLM URLs
FeliLucero1 Aug 27, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .github/workflows/capabilities_and_config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@ jobs:
run: ./connector config > config_schema.json

- name: Run and save capabilities output
# ./connector capabilities calls ResourceType() with no sync-resource-types
# filter, so clm_member's SkipEntitlements (not SkipEntitlementsAndGrants)
# reflects the all-types-enabled default; runtime differs when
# clm_workflow_queue is filtered out — see clmMemberBuilder.ResourceType().
env:
BATON_DOCUSIGN_CLIENT_ID: ${{ secrets.CLIENTID }}
BATON_DOCUSIGN_CLIENT_SECRET: ${{ secrets.CLIENTSECRET }}
Expand Down
12 changes: 9 additions & 3 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,15 @@ concurrency:
env:
# This CI account has no CLM subscription, and (unlike a C1-hosted sync) nothing here
# filters resource types by OptInRequired — every registered resource type is attempted
# by default. CLM builders now fail the whole sync rather than skip gracefully when CLM
# isn't available (see pkg/connector/clm_roles.go), so the 5 clm_* types must be
# excluded here explicitly to test the ones the three test-* jobs below care about.
# by default. Every clm_* type must stay excluded here, not just clm_workflow_queue:
# Connector.Validate() now runs an upfront CLM-readiness check (EnsureClmReady) whenever
# ANY clm_* type is in this allowlist, and it fails the whole sync loudly — before any
# resource type's List() runs — rather than tolerating a no-subscription account (see
# connector.go's Validate doc comment). Including even one clm_* type here would fail
# these jobs' group/signing-group/permission-profile coverage too, not just skip CLM.
# TestNonClmAllowlistMatchesCI
# (pkg/connector/connector_test.go) pins this list against nonClmAllowlist() as a drift
# guard.
# This is an allowlist, not a CLM-only exclusion: if you register a new non-CLM
# resource type in pkg/connector/connector.go, add it here too — otherwise it silently
# gets zero CI sync-test coverage. Declared once at the workflow level (all three jobs
Expand Down
50 changes: 41 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ Check out [Baton](https://github.com/conductorone/baton) to learn more about the
- Groups
- Signing Groups
- Permission Profiles
- CLM Members, Roles, Groups, Folders, Folder Security, and Permission Sets (requires a DocuSign CLM subscription — see [CLM Support](#clm-support))
- CLM Members, Roles, Groups, Folders, Folder Security, Permission Sets, and Workflow Queues (requires a DocuSign CLM subscription — see [CLM Support](#clm-support))

### Provisioning Support

Expand All @@ -25,6 +25,7 @@ Check out [Baton](https://github.com/conductorone/baton) to learn more about the
- CLM group membership (grant/revoke, requires a CLM subscription)
- CLM folder security (grant/revoke, requires a CLM subscription)
- CLM permission sets are synced for visibility only — the CLM API has no assignment endpoint, so they cannot be granted or revoked
- CLM workflow queue membership is synced for visibility only — the CLM API supports work-item assign/unassign, not queue-membership grant/revoke, so it cannot be granted or revoked here

## Connector Credentials

Expand Down Expand Up @@ -101,9 +102,9 @@ Copy the `code` parameter value and paste it when prompted. Save the refresh tok

DocuSign CLM (Contract Lifecycle Management) is a separate DocuSign product from
eSignature, with its own API and a separate production subscription. CLM members, roles,
groups, folders, folder security, and permission sets are opt-in: they don't sync by
default, and a customer must explicitly enable each CLM resource type in C1's sync
configuration.
groups, folders, folder security, permission sets, and workflow queues are opt-in: they
don't sync by default, and a customer must explicitly enable each CLM resource type in
C1's sync configuration.

Requirements:

Expand All @@ -115,7 +116,7 @@ Requirements:
also be granted the CLM API scopes on ConductorOne's platform side before any CLM data
will sync. Contact ConductorOne if no CLM data appears in this mode.

The 5 CLM resource types are always registered and visible to C1, but each carries
The 6 CLM resource types are always registered and visible to C1, but each carries
`OptInRequired` — C1 excludes them from a customer's sync by default, and they only run
once a customer explicitly opts in (see [CHANGE_TYPES.md](CHANGE_TYPES.md) if you're
touching this). C1's opt-in toggle does not validate the underlying DocuSign account
Expand All @@ -130,22 +131,53 @@ itself — a self-hosted connector running in service mode still has its per-res
`List()` calls filtered by the platform's opt-in selection (applied inside baton-sdk's
syncer, not surfaced to the connector's own code), but running `baton-docusign` directly
as a one-shot CLI sync (the quickstarts below, with no service/task involved at all)
attempts all 5 CLM resource types by default, with no opt-in gate at all. If that account
attempts all 6 CLM resource types by default, with no opt-in gate at all. If that account
doesn't have a CLM subscription, the sync now fails instead of skipping CLM gracefully.
Pass `--sync-resource-types` (or `BATON_SYNC_RESOURCE_TYPES`, comma-separated) with the
resource type IDs you actually want (e.g. `user,group,permission_profile`) to exclude
`clm_member,clm_role,clm_group,clm_permission_set,clm_folder` on an eSignature-only
account run this way.
`clm_member,clm_role,clm_group,clm_permission_set,clm_folder,clm_workflow_queue` on an
eSignature-only account run this way (see `.github/workflows/ci.yaml` for a working
example).

One check does NOT see that platform filter in either deployment mode: `Connector.Validate()`'s
upfront CLM-readiness check runs once, before any resource type's `List()` and before the
platform filter is applied to anything — a known, reviewed, and deliberately accepted gap,
not an oversight.

Within `List()` itself (once `Validate()` has passed and a sync is actually running), none
of the 6 CLM resource types carry their own CLM-availability tolerance logic anymore —
that responsibility now lives entirely in `Connector.Validate()`'s upfront
`EnsureClmReady()` gate (see above), which runs once, before any CLM builder's `List()`
executes. `clm_member`, `clm_group`, `clm_permission_set`, `clm_folder`, and
`clm_workflow_queue` all behave identically here: if `Validate()` passed, their `List()`
bodies just call the API and propagate whatever error comes back, same as any other
resource type; `clm_role` still makes no API call at all (a hardcoded set). An earlier
version of this connector had each CLM builder run its own per-type tolerance check
instead (with `clm_workflow_queue` as a deliberate exception that failed loud where the
others didn't) — that logic has been removed now that `Validate()` covers it once, upfront,
for all 6 types uniformly.

CLM permission sets sync for visibility only — DocuSign's CLM API has no endpoint to
assign or unassign a permission set, so they cannot be granted or revoked through this
connector.

CLM workflow queues (`clm_workflow_queue`) map to what the CLM admin console reportedly
calls "Task Groups" — that equivalence is an unconfirmed assumption, not a documented
fact, since no live CLM admin console was available to check it against. The CLM API has
no list-all endpoint for workflow queues and no reverse lookup from a queue to its
members, so `clm_workflow_queue` is modeled as `clm_member`'s `ChildResourceType`
(`pkg/connector/resource_types.go`) rather than syncing independently: the SDK calls
`clmWorkflowQueueBuilder.List()` once per synced CLM member automatically, and that call
does one `GET .../members/{id}/workflowqueues` for that member — no session store, no
independent pagination, and no member-scanning/deduping logic of its own. Membership
grants are emitted from the member side (`clmMemberBuilder.Grants()`) rather than from
`clm_workflow_queue` itself, since CLM only exposes this relationship per member. That
means `GetMemberWorkflowQueues` runs twice per member per sync (once in child-resource
`List()`, once in `Grants()`) — an accepted tradeoff of this design. Workflow queue
membership syncs for visibility only — the API supports work-item assign/unassign,
not queue-membership grant/revoke, so it cannot be granted or revoked through this
connector.

The CLM Object API's base URL is resolved via a separate account discovery call
(`GET /api/v2/{accountId}/account` on `auth.springcm.com`/`authuat.springcm.com`,
authenticated with the same access token), confirmed via DocuSign's CLM API 101
Expand Down Expand Up @@ -253,7 +285,7 @@ baton resources
- Groups
- Signing Groups
- Permission Profiles
- CLM Members, Roles, Groups, Folders, Folder Security, and Permission Sets (requires a DocuSign CLM subscription)
- CLM Members, Roles, Groups, Folders, Folder Security, Permission Sets, and Workflow Queues (requires a DocuSign CLM subscription)

# Contributing, Support and Issues

Expand Down
29 changes: 29 additions & 0 deletions baton_capabilities.json
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,13 @@
"annotations": [
{
"@type": "type.googleapis.com/c1.connector.v2.OptInRequired"
},
{
"@type": "type.googleapis.com/c1.connector.v2.ChildResourceType",
"resourceTypeId": "clm_workflow_queue"
},
{
"@type": "type.googleapis.com/c1.connector.v2.SkipEntitlements"
}
]
},
Expand Down Expand Up @@ -101,6 +108,28 @@
"permissions": {},
"optInRequired": true
},
{
"resourceType": {
"id": "clm_workflow_queue",
Comment thread
FeliLucero1 marked this conversation as resolved.
"displayName": "CLM Workflow Queue",
"traits": [
"TRAIT_GROUP"
],
"annotations": [
{
"@type": "type.googleapis.com/c1.connector.v2.SkipEntitlements"
},
{
"@type": "type.googleapis.com/c1.connector.v2.OptInRequired"
}
]
},
"capabilities": [
"CAPABILITY_SYNC"
],
"permissions": {},
"optInRequired": true
},
{
"resourceType": {
"id": "group",
Expand Down
3 changes: 2 additions & 1 deletion docs/connector.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,15 @@ sidebarTitle: "Docusign"
| CLM members, roles & groups** | <Icon icon="square-check" iconType="solid" color="#c937ae"/> | Groups only |
| CLM folders & folder security** | <Icon icon="square-check" iconType="solid" color="#c937ae"/> | <Icon icon="square-check" iconType="solid" color="#c937ae"/> |
| CLM permission sets** | <Icon icon="square-check" iconType="solid" color="#c937ae"/> | <Icon icon="square-xmark" iconType="solid" color="#c937ae"/> |
| CLM workflow queues** | <Icon icon="square-check" iconType="solid" color="#c937ae"/> | <Icon icon="square-xmark" iconType="solid" color="#c937ae"/> |
Comment thread
FeliLucero1 marked this conversation as resolved.

The Docusign connector supports [automatic account provisioning and deprovisioning](/product/admin/account-provisioning).

Every Docusign account must be assigned at least one permission profile. If all other permission profiles are revoked, the account will be automatically assigned the **DocuSign Viewer** profile, which cannot be revoked.

*By default, signing groups are not synced. Enable the **Include Signing Groups** setting to sync signing groups. Once enabled, your account must actually have the signing groups feature — ConductorOne doesn't validate this before letting you turn the setting on, so enabling it without the feature will fail the sync rather than silently sync no signing groups.

**DocuSign CLM (Contract Lifecycle Management) is a separate, separately-licensed DocuSign product. CLM resources are opt-in — enable each CLM resource type in your sync configuration to turn them on. Once enabled, your DocuSign account must have a CLM production subscription and the credential must have been granted the OAuth scopes CLM needs; enabling a CLM resource type without them will fail the sync rather than silently sync no data, since ConductorOne doesn't validate the underlying subscription before letting you opt in. CLM permission sets sync for visibility only; DocuSign's CLM API has no endpoint to assign or unassign one.
**DocuSign CLM (Contract Lifecycle Management) is a separate, separately-licensed DocuSign product. CLM resources are opt-in — enable each CLM resource type in your sync configuration to turn them on. Once enabled, your DocuSign account must have a CLM production subscription and the credential must have been granted the OAuth scopes CLM needs; enabling a CLM resource type without them will fail the sync rather than silently sync no data, since ConductorOne doesn't validate the underlying subscription before letting you opt in. CLM permission sets and workflow queues sync for visibility only; DocuSign's CLM API has no endpoint to assign or unassign a permission set, and no endpoint to grant or revoke workflow queue membership (only work-item assign/unassign, which isn't synced here). CLM workflow queues also require CLM members to be enabled — queues are discovered per member, not via a standalone list endpoint.

<Warning>
If you use **OAuth Authentication** (the default, managed method), syncing CLM data requires ConductorOne's managed OAuth app to be granted the CLM API scopes on the platform side. If CLM data doesn't appear after setup, contact ConductorOne. This doesn't apply to **Custom App (Demo Environment)**, where the connector requests the CLM scopes directly using your own DocuSign app credentials.
Expand Down
7 changes: 4 additions & 3 deletions docs/doc-info.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
— Groups
— Signing Groups
— Permissions Profile
— CLM Members, Roles, Groups, Folders, Folder Security, and Permission Sets (accounts with a DocuSign CLM subscription)
— CLM Members, Roles, Groups, Folders, Folder Security, Permission Sets, and Workflow Queues (accounts with a DocuSign CLM subscription)

2. **Can the connector provision any resources? If so, which ones?**

Expand Down Expand Up @@ -45,11 +45,12 @@

**Important Note about CLM:**

- CLM (Contract Lifecycle Management) is a separate, separately-licensed DocuSign product with its own API. The 5 CLM resource types carry `OptInRequired` and don't sync until a customer explicitly enables them in C1's sync configuration; C1's opt-in toggle doesn't validate the underlying subscription/scopes first, so an account that opts in but can't reach CLM fails the sync loudly rather than silently syncing zero CLM resources.
- CLM (Contract Lifecycle Management) is a separate, separately-licensed DocuSign product with its own API. The 6 CLM resource types carry `OptInRequired` and don't sync until a customer explicitly enables them in C1's sync configuration; C1's opt-in toggle doesn't validate the underlying subscription/scopes first, so an account that opts in but can't reach CLM fails the sync loudly rather than silently syncing zero CLM resources.
- Requires a DocuSign CLM production subscription.
- When using ConductorOne's managed OAuth app (the default cloud-hosted authentication method), CLM also requires that managed app to be granted the CLM API scope on ConductorOne's platform side — this is outside the connector's own configuration. Self-hosted or demo-environment setups using a customer-supplied DocuSign app do not have this extra requirement.
- CLM permission sets sync for visibility only; DocuSign's CLM API has no endpoint to assign or unassign one, so they cannot be granted or revoked.
- CLM members are synced as their own resource type rather than merged into the existing eSignature "Users" resource, since the two could not be confirmed to represent the same identity.
- CLM workflow queues also sync for visibility only — the API supports work-item assign/unassign, not queue-membership grant/revoke. There's no list-all endpoint for queues, so they're modeled as a child resource of CLM members: the SDK calls `clmWorkflowQueueBuilder.List()` once per synced member automatically, and membership grants are emitted from `clmMemberBuilder.Grants()`. Each member therefore triggers two `GetMemberWorkflowQueues` calls per sync (child-resource List + Grants) when workflow queues are enabled — an accepted tradeoff of this design. Workflow queues require CLM members to be enabled in the sync configuration.

---

Expand Down Expand Up @@ -171,7 +172,7 @@ DocuSign CLM is a separate, separately-licensed DocuSign product. To sync CLM da

1. Confirm your DocuSign account has a CLM production subscription.
2. Confirm the credential has been granted the CLM OAuth scopes (`spring_read`/`spring_write`).
3. The connector then syncs CLM Members, Roles, Groups, Folders, Folder Security, and Permission Sets once a customer explicitly enables each CLM resource type in C1's sync configuration (see the CLM note above — these types carry `OptInRequired`).
3. The connector then syncs CLM Members, Roles, Groups, Folders, Folder Security, Permission Sets, and Workflow Queues once a customer explicitly enables each CLM resource type in C1's sync configuration (see the CLM note above — these types carry `OptInRequired`).

If running against ConductorOne's managed OAuth app (the default cloud-hosted
production authentication method), the managed app also needs the CLM API scopes
Expand Down
Loading
Loading