|
| 1 | +# ref-unused-features |
| 2 | + |
| 3 | +SDK features that C1 does not currently use. Don't invest effort here. |
| 4 | + |
| 5 | +--- |
| 6 | + |
| 7 | +## Why This Matters |
| 8 | + |
| 9 | +The baton-sdk exposes many fields and options. Some exist for: |
| 10 | +- Future features not yet implemented |
| 11 | +- Legacy compatibility |
| 12 | +- Aspirational API design |
| 13 | + |
| 14 | +Setting these fields wastes connector development time with no benefit. |
| 15 | + |
| 16 | +--- |
| 17 | + |
| 18 | +## User Trait: Field Usage |
| 19 | + |
| 20 | +| Field | SDK Function | C1 Status | |
| 21 | +|-------|-------------|-----------| |
| 22 | +| ExternalID | `WithExternalID()` | **REQUIRED for provisioning** | |
| 23 | +| Email | `WithEmail()` | **Required** - identity matching | |
| 24 | +| Login | `WithUserLogin()` | **Required** - identity matching | |
| 25 | +| Status | `WithStatus()` | **Required** - lifecycle | |
| 26 | +| Profile | `WithUserProfile()` | Used for display | |
| 27 | +| AccountType | `WithAccountType()` | Rarely used | |
| 28 | +| MfaEnabled/MfaStatus | (no helper) | IDP connectors only | |
| 29 | +| SsoEnabled/SsoSource | (no helper) | IDP connectors only | |
| 30 | +| StructuredName | (no helper) | Rarely used | |
| 31 | +| Icon | `WithUserIcon()` | Rarely used | |
| 32 | +| Managers | (no helper) | Rarely used | |
| 33 | +| Sources | (no helper) | Rarely used | |
| 34 | + |
| 35 | +**Critical:** `WithExternalID()` is required for provisioning to work. It stores the native system identifier that Grant/Revoke operations need to call the target API. |
| 36 | + |
| 37 | +--- |
| 38 | + |
| 39 | +## ExternalID - Required for Provisioning |
| 40 | + |
| 41 | +`WithExternalID()` stores the **native system identifier** needed for provisioning operations. |
| 42 | + |
| 43 | +| Concept | Where | C1 Uses? | |
| 44 | +|---------|-------|----------| |
| 45 | +| `Resource.ExternalId` | Resource field | **YES - provisioning** | |
| 46 | +| `match_baton_id` | C1 sync config | Yes, for resource matching | |
| 47 | +| `ResourceId.Resource` | Primary identifier | **Yes** - sync matching | |
| 48 | + |
| 49 | +**The flow:** |
| 50 | +1. During sync: Set `WithExternalID(&v2.ExternalId{Id: nativeID})` |
| 51 | +2. C1 stores it with the resource |
| 52 | +3. During provisioning: SDK passes it to Grant/Revoke |
| 53 | +4. Connector calls `principal.GetExternalId().Id` to get the native ID for API calls |
| 54 | + |
| 55 | +**Recommendation:** Always set `WithExternalID()` for resources that may be involved in provisioning. |
| 56 | + |
| 57 | +--- |
| 58 | + |
| 59 | +## Group Trait: Unused Fields |
| 60 | + |
| 61 | +| Field | C1 Status | |
| 62 | +|-------|-----------| |
| 63 | +| Icon | **Ignored** | |
| 64 | +| GroupSources | **Ignored** | |
| 65 | + |
| 66 | +**What C1 reads:** |
| 67 | +- DisplayName |
| 68 | +- Profile (for display) |
| 69 | + |
| 70 | +--- |
| 71 | + |
| 72 | +## Entitlement: Unused Options |
| 73 | + |
| 74 | +| Option | SDK Function | C1 Status | |
| 75 | +|--------|-------------|-----------| |
| 76 | +| Purpose | `WithPurpose()` | **Ignored** | |
| 77 | +| RiskLevel | `WithRiskLevel()` | **Ignored** | |
| 78 | +| Compliance | `WithComplianceFramework()` | **Ignored** | |
| 79 | + |
| 80 | +**What C1 reads:** |
| 81 | +- Slug (for grant matching) |
| 82 | +- DisplayName |
| 83 | +- Description |
| 84 | +- GrantableTo (for UI filtering) |
| 85 | + |
| 86 | +--- |
| 87 | + |
| 88 | +## Grant: Options |
| 89 | + |
| 90 | +| Option | SDK Function | C1 Status | |
| 91 | +|--------|-------------|-----------| |
| 92 | +| Principal | (required) | **Yes** | |
| 93 | +| Entitlement | (required) | **Yes** | |
| 94 | +| ID | (auto-generated) | **Yes** - for revocation | |
| 95 | + |
| 96 | +**Note:** Grant ExternalId annotation is different from Resource ExternalId. Grant annotations are rarely needed. |
| 97 | + |
| 98 | +--- |
| 99 | + |
| 100 | +## Annotations: Limited Use |
| 101 | + |
| 102 | +Most annotations are for internal SDK use: |
| 103 | + |
| 104 | +| Annotation | Purpose | C1 Use | |
| 105 | +|------------|---------|--------| |
| 106 | +| RateLimitDescription | Rate limit metadata | SDK internal | |
| 107 | +| RequestId | Request tracking | SDK internal | |
| 108 | +| NextPage | Pagination hint | SDK internal | |
| 109 | +| Profile | Generic metadata | **Sometimes** | |
| 110 | +| ExternalId | External reference | **Ignored** | |
| 111 | + |
| 112 | +**Recommendation:** Don't add custom annotations expecting C1 to read them. |
| 113 | + |
| 114 | +--- |
| 115 | + |
| 116 | +## Metadata Capabilities |
| 117 | + |
| 118 | +The `baton_capabilities.json` file is auto-generated. Manual edits are overwritten. |
| 119 | + |
| 120 | +Capabilities that are declared but have limited C1 support: |
| 121 | +- Custom resource types beyond User/Group/Role/App |
| 122 | +- Complex permission hierarchies |
| 123 | +- Multi-level delegation |
| 124 | + |
| 125 | +--- |
| 126 | + |
| 127 | +## Features That Look Useful But Aren't |
| 128 | + |
| 129 | +### "Rich" User Profiles |
| 130 | + |
| 131 | +```go |
| 132 | +// Tempting but wasted effort |
| 133 | +rs.WithUserProfile(map[string]interface{}{ |
| 134 | + "department": user.Department, |
| 135 | + "title": user.Title, |
| 136 | + "manager": user.Manager, |
| 137 | + "costCenter": user.CostCenter, |
| 138 | + "location": user.Location, |
| 139 | + "employeeId": user.EmployeeId, |
| 140 | + "startDate": user.StartDate, |
| 141 | + "badge_photo": user.PhotoURL, |
| 142 | + // ... 20 more fields |
| 143 | +}) |
| 144 | +``` |
| 145 | + |
| 146 | +C1 displays these in the UI but doesn't use them for access decisions. |
| 147 | + |
| 148 | +**Recommendation:** Include fields useful for human identification (name, department, title). Skip everything else. |
| 149 | + |
| 150 | +### Structured Names |
| 151 | + |
| 152 | +```go |
| 153 | +// The SDK has this, but C1 ignores it |
| 154 | +type StructuredName struct { |
| 155 | + GivenName string |
| 156 | + FamilyName string |
| 157 | + Formatted string |
| 158 | +} |
| 159 | +``` |
| 160 | + |
| 161 | +Just use the display name string. |
| 162 | + |
| 163 | +### Icon/Photo URLs |
| 164 | + |
| 165 | +C1 doesn't fetch or display custom icons. Default icons are used. |
| 166 | + |
| 167 | +--- |
| 168 | + |
| 169 | +## What TO Focus On |
| 170 | + |
| 171 | +These fields matter for C1 sync and provisioning: |
| 172 | + |
| 173 | +### Users |
| 174 | +- `Email` - Identity matching |
| 175 | +- `Login` - Identity matching |
| 176 | +- `Status` - Lifecycle management |
| 177 | +- `ResourceId` - Stable, unique identifier |
| 178 | + |
| 179 | +### Groups |
| 180 | +- `DisplayName` - UI display |
| 181 | +- `ResourceId` - Stable identifier |
| 182 | +- Member entitlement - Grant/revoke |
| 183 | + |
| 184 | +### Roles |
| 185 | +- `DisplayName` - UI display |
| 186 | +- `ResourceId` - Stable identifier |
| 187 | +- Assignment entitlement - Grant/revoke |
| 188 | + |
| 189 | +### Grants |
| 190 | +- `Principal` - Who has access |
| 191 | +- `Entitlement` - What access |
| 192 | +- Correct entity sources (principal vs entitlement) |
| 193 | + |
| 194 | +--- |
| 195 | + |
| 196 | +## How to Know If a Feature Is Used |
| 197 | + |
| 198 | +1. **Check C1 UI** - If you can't see it in the app, it's not used |
| 199 | +2. **Ask C1 team** - "Does C1 use X field for anything?" |
| 200 | +3. **Check this document** - Updated based on analysis |
| 201 | + |
| 202 | +When in doubt, implement the minimum and iterate based on actual C1 needs. |
| 203 | + |
| 204 | +--- |
| 205 | + |
| 206 | +## Historical Note |
| 207 | + |
| 208 | +Some unused features exist because: |
| 209 | +- Planned for future roadmap items |
| 210 | +- Added for specific customer requests that didn't ship |
| 211 | +- Legacy compatibility with older SDK versions |
| 212 | +- Aspirational "complete" API design |
| 213 | + |
| 214 | +The SDK API is broader than what C1 currently consumes. |
0 commit comments