[AUT-13970] Keep phone_provider_config through a tenant pull/push - #51
Merged
Merged
Conversation
storeTenant filters the tenant root through smodels.Tenant to drop the collections written to their own files. That struct predates phone_provider_config, so the field was discarded on pull and could never be pushed back — which is why affected repos have no phone provider configuration on disk at all. Bumps acp-client-go to the AUT-13969 sync so the config carries `mode`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AZykgo2CbxHjvnBzfWQxrL
There was a problem hiding this comment.
Pull request overview
This PR updates tenant config-as-code persistence so phone_provider_config is no longer dropped when writing tenant.yaml, enabling it to survive a pull/push round trip.
Changes:
- Introduces a
tenantFilewrapper type to includephone_provider_configwhile still stripping sub-resources stored in separate files. - Adds/extends tests to validate
phone_provider_configserialization and end-to-end round-trip preservation. - Bumps
github.com/cloudentity/acp-client-goto a commit pseudo-version and updates golden YAML fixtures for newly surfaced fields.
Reviewed changes
Copilot reviewed 4 out of 5 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| internal/cac/storage/tenant_storage.go | Writes tenant.yaml via a new wrapper type to preserve phone_provider_config. |
| internal/cac/storage/tenant_storage_test.go | Adds fixture updates and new tests covering phone_provider_config persistence/round-trip. |
| internal/cac/storage/server_storage_test.go | Updates golden YAML expectations for new fields from the client bump. |
| go.mod | Pins acp-client-go to a specific commit pseudo-version required by upstream work. |
| go.sum | Updates checksums for the new acp-client-go pseudo-version. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Follows the pattern server storage already uses for singular sub-resources (claims, consent, ciba, theme_binding): writeFile on the way out, readFileToMap on the way back. Replaces the earlier approach of widening the tenant.yaml model. That one broke the invariant behind utils.TenantRootKeys, which is derived from the same type storeTenant serializes into — phone_provider_config was written to tenant.yaml but missing from the root key set, so `push --filter root` silently dropped it. storeTenant is now untouched and the invariant holds. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AZykgo2CbxHjvnBzfWQxrL
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 4 out of 5 changed files in this pull request and generated 1 comment.
Suppressed comments (1)
go.mod:7
- The explicit merge prerequisite is still unmet: this pseudo-version points to ciam-client-go#75's head commit, and that PR is currently open, draft, and blocked rather than merged to
master. Re-pin this dependency to the resultingmasterpseudo-version after #75 lands; the current pin should not be merged.
github.com/cloudentity/acp-client-go v0.0.0-20260820095634-1f1938087bcf
…trip test Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AZykgo2CbxHjvnBzfWQxrL
ikawalec
approved these changes
Aug 24, 2026
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QrGXNzbqi2CPHE4nWHri7N
piotrek-janus
approved these changes
Aug 31, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Jira task
AUT-13970
Important
Do not merge before ciam-client-go#75.
go.modcurrently pins that PR's branch commit (1f193808) so this builds and tests green today; it needs re-pinning to amasterpseudo-version once #75 lands. #75 is itself gated on a Customer Success sign-off.Release Notes Description (public)
Tenant phone provider configuration can now be managed as code.
cac pullwrites it tophone_provider_config.yamlandcac pushsends it back. Previously it was dropped on pull and could not be pushed at all.SMS and voice delivery — including Twilio credentials and sender ID — is configured through the tenant's phone provider configuration. It is no longer driven by the
providerfield on an SMS or voice MFA method; that field is deprecated and no longer selects a messaging provider.If you use
--filter, addphone_provider_configto the list.--filternames what to include, so phone provider configuration is only sent when you ask for it:Runs without
--filterinclude it automatically.Implementation details (internal)
Problem.
TenantStoragenever handledphone_provider_config.storeTenantserializes the tenant root throughsmodels.Tenantto strip sub-resources that live in their own files, and that struct — the Tenant API resource — has no such field, because server-side a phone provider configuration is a separate entity, not a tenant attribute. Nothing else picked it up either, so it was dropped on pull and could never be pushed back. This is why affected repositories contain no phone provider configuration at all, and it's the client-side half of the AUT-13968 incident.Solution. Treat it as what it is — a singular sub-resource — and give it its own file, exactly as server storage already does for
claims,consent,ciba,theme_bindingand friends:writeFile(model.PhoneProviderConfig, path/phone_provider_config)on the way outreadFileToMap(tenant, "phone_provider_config", ...)on the way backstoreTenantandtenant.yamlare untouched.An earlier revision of this PR instead widened the model
storeTenantserializes into. That was wrong:utils.TenantRootKeysis derived from the same type, deliberately, so that root-level keys stay in sync without a hand-maintained list. Widening one without the other wrotephone_provider_configintotenant.yamlwhile leaving it out of the root key set, sopush --filter rootsilently dropped it. Keeping it a sub-resource avoids the coupling entirely.Filter behaviour now matches
mfa_methods:Also bumps
acp-client-goto the AUT-13969 spec sync soTreePhoneProviderConfigcarriesmode. Without it the config would round-trip mode-less, which is the shape that caused the original wipe.Tests.
TestTenantStorage/phone_provider_config— asserts the config lands inphone_provider_config.yamlandtenant.yamlstays cleanTestTenantStoragePhoneProviderConfigRoundTrip— Write → Read → model, asserting mode and credentials surviveBoth falsification-checked: dropping the
writeFilecall fails the round-trip with "phone_provider_config did not survive the round trip", and passes again when restored.Two golden fixtures are updated for fields the client bump adds (
require_user_interaction_before_prompt,enforce_application_membership,skip_dbfp). Full suite green with noreplacedirective.Note for reviewers: a
cac pullafter this change adds a newphone_provider_config.yamlto repositories whose tenant has one. Credentials land in that file rather than intenant.yaml.Out of scope, but noted: the same gap also drops tenant-level
featuresandtranslations, both of which are maps and would want thepools/mfa_methodsdirectory treatment. Left as-is deliberately.Reference
Twilio Enum Drift — the breaking-change analysis behind the client bump this PR depends on, including why the
twilioprovider value affects every migrated tenant rather than only stale checkouts. Access-controlled; ask if you need it opened up.