diff --git a/baton/argo-cd.mdx b/baton/argo-cd.mdx
index c49461ca..4e37472f 100644
--- a/baton/argo-cd.mdx
+++ b/baton/argo-cd.mdx
@@ -8,16 +8,69 @@ sidebarTitle: "ArgoCD"
## Capabilities
-| Resource | Sync | Provision |
-| :--- | :--- | :--- |
-| Accounts | | |
-| Roles | | |
+| Resource | Sync | Provision | Deprovision |
+| :--- | :--- | :--- | :--- |
+| Accounts | | | |
+| Roles | | | — |
-The ArgoCD connector supports [automatic account provisioning](/product/admin/account-provisioning).
+The ArgoCD connector supports [automatic account provisioning and deprovisioning](/product/admin/account-provisioning).
When a new account is created by C1, the account's password will be sent to a [vault](/product/admin/vaults).
-This connector does not support account deprovisioning. You must deprovision accounts directly in ArgoCD.
+The connector also supports credential rotation for local accounts: C1 sets a new random password
+and sends it to a vault. ArgoCD rejects every session and API token issued before a password
+change, so rotation also cuts off the account's existing access.
+
+## Connector actions
+
+Connector actions are custom capabilities that extend C1 automations with app-specific operations.
+
+| Automation step | Actions offered | How the target is selected |
+| :--- | :--- | :--- |
+| Account lifecycle action | `enable_user`, `disable_user` | The step's own target-account selector — either the account in context or a specific account. C1 resolves `user_id` from that account. |
+| [Perform connector action](/product/admin/automations-steps-reference#perform-connector-action) | `revoke_tokens` | Set `user_id` to the ArgoCD account name. |
+
+| Action name | Additional fields | Description |
+| :--- | :--- | :--- |
+| `disable_user` | `user_id` (string, required) | Disables an ArgoCD local account. ArgoCD rejects the account's password and API tokens while it is disabled. Reversible with `enable_user`. |
+| `enable_user` | `user_id` (string, required) | Re-enables a disabled ArgoCD local account, restoring its existing password and API tokens. |
+| `revoke_tokens` | `user_id` (string, required) | Revokes every API token issued to an ArgoCD local account. The account, its password and its enabled state are unchanged. Run it with `disable_user` when a re-enabled account must not get its old tokens back. |
+
+## Account lifecycle
+
+The connector manages ArgoCD **local accounts**. ArgoCD's Account API exposes no delete, disable
+or enable endpoint, so the connector changes accounts through the Kubernetes API, using the
+permissions described in [Gather ArgoCD credentials](#gather-argocd-credentials).
+
+- **Disable / enable** (the `disable_user` and `enable_user` actions) are reversible. The account
+ keeps its password and API tokens, which ArgoCD refuses while the account is disabled and
+ accepts again once it is enabled.
+- **Revoke API tokens** (the `revoke_tokens` action) removes the account's API tokens without
+ touching the account itself.
+- **Rotate password** (credential rotation) sets a new random password and invalidates every
+ session and API token issued before it.
+- **Delete** (account deprovisioning) is permanent. It revokes the account's API tokens, removes
+ its role grants and direct permissions, removes the account, and purges its stored credentials,
+ so an account created later with the same name inherits none of them.
+
+Use `disable_user` to suspend access you may need to restore, and delete to remove the account
+for good.
+
+**Notes:**
+
+- The built-in `admin` account cannot be disabled, enabled, rotated, stripped of its tokens or
+ deleted. The connector also refuses to do any of these, except enable, to the account it
+ authenticates as, since it would lock itself out of ArgoCD. SSO/Dex-managed identities are not
+ local accounts, so there is nothing for the connector to manage for them.
+- Disabling a disabled account, enabling an enabled account, revoking the tokens of an account
+ that has none, or deleting an account that is already gone is reported as success. The actions
+ and rotation fail with a not-found error for an account ArgoCD does not know.
+- Account names may contain only alphanumerics, `-` and `_`. Names containing `.` are rejected,
+ since ArgoCD cannot address them as accounts.
+- Deleting an account rewrites `policy.csv` in `argocd-rbac-cm`, which removes its `#` comment lines.
+- Revoking tokens and rotating another account's password need the `accounts, update` ArgoCD RBAC
+ permission for the connector's account. Deleting accounts also requires the `secrets` Kubernetes
+ permissions described below.
## Gather ArgoCD credentials
@@ -25,10 +78,12 @@ Configuring the connector requires you to pass in credentials generated in ArgoC
### Create a Role with required permissions
-The connector needs permissions to read and modify ArgoCD ConfigMaps. Create a Role that grants access to the following ConfigMaps:
+The connector needs permissions to read and modify ArgoCD ConfigMaps, and to read and patch the
+ArgoCD Secret. Create a Role that grants access to the following objects:
-- `argocd-rbac-cm`: Contains RBAC policies and role grants (needs read and write access)
-- `argocd-cm`: Contains ArgoCD configuration including user accounts (needs write access for provisioning)
+- `argocd-rbac-cm` ConfigMap: Contains RBAC policies and role grants (needs read and write access)
+- `argocd-cm` ConfigMap: Contains ArgoCD configuration including user accounts (needs write access for provisioning, deprovisioning and the enable/disable actions)
+- `argocd-secret` Secret: Contains local accounts' password hashes and API token records (needs read and write access for account deletion)
```yaml
apiVersion: rbac.authorization.k8s.io/v1
@@ -40,6 +95,10 @@ rules:
- apiGroups: [""]
resources: ["configmaps"]
verbs: ["get", "list", "patch", "update"]
+ - apiGroups: [""]
+ resources: ["secrets"]
+ resourceNames: ["argocd-secret"]
+ verbs: ["get", "patch"]
```
**Required Permissions Explained:**
@@ -48,6 +107,13 @@ rules:
- `list`: List ConfigMaps in the namespace (required to discover and access the ConfigMaps)
- `patch`: Partially update ConfigMaps (used to modify RBAC policies and user accounts)
- `update`: Fully update ConfigMaps (used as an alternative to patch for modifying ConfigMaps)
+- `get`/`patch` on `secrets`: Read and purge a deleted account's stored credentials in `argocd-secret`. Restricted to that one Secret by name, so the connector cannot read the repository and cluster credentials that also live in the `argocd` namespace. Only needed for account deletion; omit the rule entirely if you do not use it.
+
+
+ The `argocd-secret` permissions are new. Existing deployments must re-apply this role before
+ account deletion is used. Without them the credential-purge step fails with a `403` after the
+ account has already been deleted, leaving its stored credentials in place.
+
Apply with:
diff --git a/baton/azure-devops.mdx b/baton/azure-devops.mdx
index d99ae4c0..32efc201 100644
--- a/baton/azure-devops.mdx
+++ b/baton/azure-devops.mdx
@@ -146,7 +146,8 @@ You can authenticate the Azure DevOps connector in three ways: OAuth (interactiv
- vso.graph
- vso.tokenadministration (required to sync personal access tokens)
- vso.auditlog (required if you enable incremental sync)
- - vso.identity (optional — required only when **Legacy group identity resolution** is enabled)
+ - vso.identity (optional — required when **Legacy group identity resolution** is enabled, or to sync all team administrators)
+ - vso.security\_manage (optional — required to sync all team administrators)
**For full provisioning (read/write) access:**
- user\_impersonation (required - Azure DevOps only allows delegated permissions)
@@ -155,7 +156,8 @@ You can authenticate the Azure DevOps connector in three ways: OAuth (interactiv
- vso.memberentitlementmanagement\_write
- vso.tokenadministration (required to sync personal access tokens)
- vso.auditlog (required if you enable incremental sync)
- - vso.identity (optional — required only when **Legacy group identity resolution** is enabled)
+ - vso.identity (optional — required when **Legacy group identity resolution** is enabled, or to sync all team administrators)
+ - vso.security\_manage (optional — required to sync all team administrators)
Click **Add permissions**.
@@ -267,6 +269,9 @@ Azure DevOps groups, configure the connector with OAuth
To enable incremental sync (optional):
- **Audit Log: Read** - Required if you want to enable the incremental sync feature, which syncs only changes since the last sync (`vso.auditlog`)
- **Identity: Read** - Required only if you also enable **Legacy group identity resolution** to resolve legacy group descriptors via the Identities API (`vso.identity`). This setting defaults to off and is separate from Graph: Read.
+ To sync all team administrators, including those who aren't team members (optional):
+ - **Security: Manage** - Required to read the team's administrators (`vso.security_manage`)
+ - **Identity: Read** - Required to identify each team administrator (`vso.identity`)
Click **Create**.
diff --git a/baton/azure.mdx b/baton/azure.mdx
index 91ad4dc1..639f0a6a 100644
--- a/baton/azure.mdx
+++ b/baton/azure.mdx
@@ -15,6 +15,7 @@ The Microsoft Azure connector uses the [Cloud Infrastructure Access](/product/ad
| Accounts | | |
| Groups | | |
| Managed identities | | |
+| Enterprise applications | | |
| Azure roles | | |
| Tenant root | | |
| Management groups | | |
@@ -22,7 +23,7 @@ The Microsoft Azure connector uses the [Cloud Infrastructure Access](/product/ad
| Subscriptions | | |
| Azure resources (opt-in) | | |
- This connector pulls account, group, and managed identity information from the Entra ID connector. You'll configure this relationship when setting up the connector.
+ This connector pulls account, group, managed identity, and enterprise application information from the Entra ID connector. You'll configure this relationship when setting up the connector.
## Gather Azure credentials
@@ -168,10 +169,68 @@ az role assignment delete \
### Optional configuration
-Two additional settings are available in the connector's configuration form:
+Three additional settings are available in the connector's configuration form:
- **Azure cloud** — the Azure cloud environment to connect to: `public` (default), `usgovernment`, or `china`. This is the only way to point the connector at the US Government or China clouds instead of the public Azure cloud.
- **Skip roles with no assignments** — when enabled, only Azure roles with at least one active assignment are synced, instead of every role definition in scope.
+- **Sync sub-resources** — which kinds of nested sub-resource to sync. Leave empty to sync none. Sub-resources are not a separate resource type: each one is synced as an **Azure resource**, nested under the Azure resource that owns it.
+
+
+**Sync sub-resources only has an effect if the Azure resources resource type is enabled.**
+
+Sub-resources are synced as children of the Azure resources that own them — a blob container is
+synced under its storage account. If Azure resources are not being synced, there are no parents
+to sync them under, and enabling this setting does nothing.
+
+
+#### Supported sub-resource types
+
+Each value below is a scope Azure documents as directly role-assignable. Everything listed here
+syncs as an Azure resource — the values select which kinds are included, not which resource types
+exist. Select only the ones you need: **each selected value costs one extra API call per parent
+resource, on every sync.**
+
+| Value | Syncs, as an Azure resource | Nested under |
+| :--- | :--- | :--- |
+| `blob_containers` | Blob containers | Storage accounts |
+| `storage_queues` | Storage queues | Storage accounts |
+| `storage_tables` | Storage tables | Storage accounts |
+| `service_bus_queues` | Service Bus queues | Service Bus namespaces |
+| `service_bus_topics` | Service Bus topics | Service Bus namespaces |
+| `event_hubs` | Event hubs | Event Hubs namespaces |
+| `subnets` | Subnets | Virtual networks |
+
+Not currently supported: Key Vault secrets, keys and certificates (listing them requires a Key
+Vault data-plane connection, which is separate from the Azure Resource Manager access this
+connector uses), Azure Files shares, Service Bus topic subscriptions, and Event Hubs consumer
+groups.
+
+#### Why sync sub-resources
+
+Azure allows a role to be assigned directly at a sub-resource scope. A common example is granting
+`Storage Blob Data Contributor` on a single blob container rather than on the whole storage
+account:
+
+```
+/subscriptions/{id}/resourceGroups/{rg}/providers/Microsoft.Storage/storageAccounts/{account}/blobServices/default/containers/{container}
+```
+
+Assignments made at those scopes are only visible in C1 if the sub-resource itself is synced.
+With this setting disabled, access granted on an individual container does not appear anywhere,
+even though the storage account above it syncs normally.
+
+The trade-off is API calls: each selected type costs one additional request per parent resource
+per sync — selecting all three storage types means three extra calls for every storage account in
+the tenant. That is why nothing is selected by default, and why the types are chosen individually
+rather than with a single on/off switch.
+
+
+If a resource cannot be listed because it does not offer that sub-resource at all — a disabled
+storage account, or a Premium account that has no queue or table service — the connector skips it
+and continues syncing everything else. A permissions error is different: if the connector is not
+allowed to list a resource's children, the sync fails, because silently syncing less access than
+exists would be misleading.
+
## Configure the Azure connector
@@ -227,8 +286,9 @@ Click **Save**.
Finally, tell the connector where to find the identities that will be used for this app in C1.
1. In the **Shared identity source** area of the page, click **Edit**.
2. Select your Entra connector.
- 3. **Optional.** Limit the identities pulled from the connector you selected to only those with a certain entitlement by setting the entitlement.
- 4. Click **Save**.
+ 3. Under **Only import identities of type**, select **Users**, **Groups**, and **Apps**. Azure reports both managed identities and enterprise applications as service principals, so role assignments held by an enterprise application only resolve when **Apps** is selected.
+ 4. **Optional.** Limit the identities pulled from the connector you selected to only those with a certain entitlement by setting the entitlement.
+ 5. Click **Save**.
The connector's label changes to **Syncing**, followed by **Connected**. You can view the logs to ensure that information is syncing.
diff --git a/baton/coupa.mdx b/baton/coupa.mdx
index 19381edf..174a7fc5 100644
--- a/baton/coupa.mdx
+++ b/baton/coupa.mdx
@@ -50,7 +50,7 @@ C1 can create Coupa user accounts. When you configure account provisioning for t
Every field is optional to C1. Map **First name** and **Last name** regardless — Coupa has no other source for a new user's name.
-Accounts are created active. Coupa authenticates through SSO, so no password is set.
+Accounts are created active. The connector does not set a password.
Custom fields are sent in Coupa's `custom-fields` namespace. License assignments can also be managed after account creation through C1 License Management.
diff --git a/baton/databricks.mdx b/baton/databricks.mdx
index 7e61eccb..4e8ca893 100644
--- a/baton/databricks.mdx
+++ b/baton/databricks.mdx
@@ -21,13 +21,9 @@ The Databricks connector supports [automatic account provisioning and deprovisio
[This connector syncs non-human identities](/product/admin/nhi) and displays them on the **Identities overview** dashboard.
-
-Provisioning **account groups** requires OAuth authentication. It is not available when authenticating with a workspace token, because the Databricks API does not allow provisioning account groups from a workspace token. Workspace-scoped groups can still be provisioned with a workspace token.
-
-
## Authentication methods
-The connector authenticates with **OAuth** — an account-level service principal's client ID and secret. This is the only method currently offered.
+The connector authenticates with **OAuth** — an account-level service principal's client ID and secret. This is the only authentication method the connector supports.
## Gather Databricks credentials