Lite: non-interactive Azure auth (service principal + managed identity) — #1038#1042
Merged
Conversation
…y) — #1038 Adds two non-interactive Azure SQL auth modes to Lite so a fleet of Azure SQL instances can authenticate without per-server interactive prompts: - ServicePrincipal: ActiveDirectoryServicePrincipal (client id + secret) - ManagedIdentity: ActiveDirectoryManagedIdentity (system- or user-assigned) Changes: - AuthenticationTypes: add ServicePrincipal / ManagedIdentity constants. - ServerConnection: AzureClientId / AzureTenantId / ManagedIdentityClientId (non-secret) model fields; SP + MI connection-string arms; GetConnectionString fetches the SP secret (none for MI); HasStoredCredentials (MI=true, SP=cred manager); AuthenticationDisplay arms. Auth keyword logic extracted into a shared ApplyAuthentication helper so the two build sites can't diverge. - ServerManager: save SP secret on Add/Update; explicit orphan-secret delete on switch to MI/Windows; DeleteServer already clears it. - AddServerDialog: SP + MI radios/panels (shared Grid.Row=7 toggle), edit-load pre-fill of SP client id + secret from Credential Manager, persist new fields, Test-Connection builder routed through the shared helper. Security: the SP secret lives ONLY in Windows Credential Manager (DPAPI) via the existing per-server-GUID CredentialService. It is never a serialized model property (not in servers.json) and never logged. Dependency note: SP/MI ride the AAD providers in the already-referenced Microsoft.Data.SqlClient.Extensions.Azure 1.0.0 (same infra as EntraMFA). No new NuGet added; that reference is load-bearing for SP + MI + EntraMFA. Tests: connection-string shape for SP/MI (incl. system- vs user-assigned), GetConnectionString secret fetch, HasStoredCredentials, AuthenticationDisplay, two-build-site auth parity, and regression for Windows/SqlServer/EntraMFA. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
… with a blank username (LOW-1) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
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.
What shipped (Phase A of #1038)
Two non-interactive Azure SQL auth modes for Lite, so a fleet of Azure SQL instances can authenticate with no per-server interactive prompt:
Authentication=ActiveDirectoryServicePrincipal, client id + client secret.Authentication=ActiveDirectoryManagedIdentity, system-assigned (no id) or user-assigned (client id).Both ride the same AAD provider infrastructure that already powers EntraMFA, selected via the
Authentication=keyword. Per-server (credential profiles are deferred Phase B).Changes
AuthenticationTypes:ServicePrincipal/ManagedIdentityconstants (additive, backward compatible).ServerConnection: non-secret model fieldsAzureClientId/AzureTenantId(stored-but-unused; MDS resolves tenant from the server authority) /ManagedIdentityClientId; SP + MI connection-string arms;GetConnectionStringfetches the SP secret (MI fetches nothing);HasStoredCredentials(MI = true, SP = Credential-Manager check);AuthenticationDisplayarms (was a silent_ => "Windows"). Auth-keyword logic extracted into a sharedApplyAuthenticationhelper.ServerManager: save SP secret on Add/Update; explicit orphan-secret delete when switching SP→MI / SP→Windows;DeleteServeralready clears it.AddServerDialog(XAML + code-behind): SP + MI radios and panels (sharedGrid.Row=7visibility toggle); MI panel carries the workstation-vs-Azure note; edit-load pre-fills the SP client id + secret from Credential Manager (mirrors the SQL-password pre-fill); persists the new fields; Test-Connection builder routed through the shared helper.Two-build-site handling
The dialog's
BuildConnectionBuilder(Test Connection) andServerConnection.BuildConnectionString(production) are the two auth-deciding build sites. Rather than maintain two parallel arm-sets, both now call the sharedServerConnection.ApplyAuthentication. A parity test asserts they emit identicalAuthentication/UserID/Password/IntegratedSecurityfor every auth mode.Security
CredentialService. It is never a serialized model property (not inservers.json) and never logged (no connection-string-on-error path).Dependency note
No new NuGet. SP/MI use the AAD providers in the already-referenced
Microsoft.Data.SqlClient.Extensions.Azure 1.0.0(transitively MSAL + Azure.Identity). That reference is load-bearing — if it is dropped/bumped, SP + MI + EntraMFA break together.Build + test (real results)
New tests: SP shape (ActiveDirectoryServicePrincipal, UserID=clientId, Password=secret, IntegratedSecurity=false, Encrypt honored); MI system- and user-assigned;
GetConnectionStringSP-secret fetch / MI no-fetch;HasStoredCredentials(MI true, SP cred-manager);AuthenticationDisplay; two-build-site parity; Windows/SqlServer/EntraMFA regression.Maintainer Azure E2E checklist (plan §9 — cannot be unit-tested without a tenant)
🤖 Generated with Claude Code