AgentStack
SKILL verified MIT Self-run

Sqlmigration Security Review

skill-vanterx-mssql-performance-skills-sqlmigration-security-review · by vanterx

Audits the security-object migration plan for a SQL Server move with 15 checks (J1-J15) — logins, server and database permissions, credentials, certificates/keys ownership, and Central Management Server registrations. Use this skill when a user is migrating a SQL Server database or instance and needs to carry over logins, permissions, credentials, or certificates, or asks "will my logins still wo…

No reviews yet
0 installs
5 views
0.0% view→install

Install

$ agentstack add skill-vanterx-mssql-performance-skills-sqlmigration-security-review

✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures

What it can access

  • Network access No
  • Filesystem access No
  • Shell / process execution No
  • Environment & secrets No
  • Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

Are you the author of Sqlmigration Security Review? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

sqlmigration-security-review

Purpose

Reviews the security-object family of a SQL Server migration — the slice sqlmigration-review dispatches here rather than checking itself. This skill owns 15 checks (J1–J15) covering whether logins, server/database permissions, credentials, certificate/key ownership, and Central Management Server (CMS) registrations will survive a backup/restore or log shipping/Always On AG seeding migration, and what breaks if they don't.

  • Login Portability (J1–J5) — orphaned users after restore, SID mismatch, login type

unsupported on target platform, password policy differences, default database missing

  • Permission Fidelity (J6–J9) — server-level role membership, database-level role membership,

explicit GRANT/DENY statements, ownership chains crossing the migration boundary

  • Credentials & Secrets (J10–J12) — SQL Server Credential objects, proxy account mapping,

linked server stored logins

  • Certificates & Keys (J13–J14) — certificate/key migration for objects that depend on them

(excluding TDE, which is sqlencryption-review's domain), backup of certificates before cutover

  • CMS (J15) — Central Management Server registration entries pointing at the old instance name

All fix recipes use native T-SQL system views (sys.server_principals, sys.database_principals, sys.credentials), the in-box SqlServer PowerShell module, and the native sp_help_revlogin script — no third-party module is referenced or required.

Input

Accepts any of the following:

  1. Source and target server facts pasted as text — login lists, permission grants, target

platform

  1. Capture script output (.txt/.csv) — see scripts/capture-security-facts.sql
  2. Natural-language description — "migrating 40 logins, half are Windows groups, target is

Azure SQL Database"

  1. File path to a directory of exported artifactssp_helplogins text dumps, SSMS

Generate Scripts output for logins/users

Recommended capture (run on the source instance):

SELECT name, type_desc, is_disabled, default_database_name,
       SUSER_SID(name) AS sid
FROM sys.server_principals
WHERE type IN ('S','U','G') AND name NOT LIKE '##%';

SELECT dp.name AS user_name, dp.type_desc, sp.name AS login_name
FROM sys.database_principals dp
LEFT JOIN sys.server_principals sp ON dp.sid = sp.sid
WHERE dp.type IN ('S','U','G');

SELECT name, credential_identity FROM sys.credentials;

-- TDE encryptor certs also have is_active_for_begin_dialog = 0, so anti-join the DEK view to drop them
SELECT c.name, c.certificate_id, c.expiry_date, c.pvt_key_encryption_type_desc
FROM sys.certificates c
WHERE NOT EXISTS (SELECT 1 FROM sys.dm_database_encryption_keys dek
                  WHERE dek.encryptor_thumbprint = c.thumbprint);

Category 1 — Login Portability

J1 — Orphaned Database User After Restore

Trigger: A database user's SID (sys.database_principals.sid) has no matching login SID (sys.server_principals.sid) on the target instance after restore. Severity: Critical Fix: Run ALTER USER [username] WITH LOGIN = [username]; for each orphaned user once the matching login exists on the target, or use sp_help_revlogin's generated script to recreate logins with matching SIDs before the restore completes.

J2 — SQL Authentication Login SID Mismatch Risk

Trigger: Migration plan creates new SQL-authentication logins on the target manually (e.g., via CREATE LOGIN) rather than scripting them from the source with matching SIDs. Severity: Critical Fix: Generate the login-creation script from the source using sp_help_revlogin (in-box system stored procedure, or its documented script form), which preserves the original SID and hashed password — manually re-typing CREATE LOGIN statements produces a new SID and orphans every database user mapped to that login.

J3 — Login Type Unsupported on Target Platform

Trigger: Source has Windows-authenticated logins/groups, certificate-mapped logins, or asymmetric-key-mapped logins, and the target platform is Azure SQL Database (no Windows Auth support) or otherwise cannot host that login type. Severity: Critical Fix: Map Windows logins to Microsoft Entra ID identities for Azure SQL Database targets; confirm certificate/key-mapped login support on the specific target platform before migrating — see /sqlmigration-review Y8 for the broader Azure platform check.

J4 — Password Policy / Expiration Settings Differ From Source

Trigger: Source logins have CHECK_POLICY/CHECK_EXPIRATION settings that depend on a domain password policy not enforced identically on the target (e.g., target is a workgroup server or Azure SQL Database with no domain policy). Severity: Warning Fix: Re-evaluate each migrated login's CHECK_POLICY/CHECK_EXPIRATION settings explicitly on the target rather than assuming the source's domain policy carries over silently.

J5 — Migrated Login's Default Database Does Not Exist on Target

Trigger: A login's default_database_name references a database that either was not part of the migration scope or has a different name on the target. Severity: Warning Fix: ALTER LOGIN [loginname] WITH DEFAULT_DATABASE = [target_db_name]; for each affected login after the database has been migrated and renamed (if applicable).

Category 2 — Permission Fidelity

J6 — Server-Level Role Membership Not Re-Created

Trigger: Source login is a member of a fixed or user-defined server role (sys.server_role_members), and the migration plan's login-recreation script does not include role membership statements. Severity: Critical Fix: Script ALTER SERVER ROLE [rolename] ADD MEMBER [loginname]; for every server-role membership captured on the source, and run it immediately after login creation on the target.

J7 — Database Role Membership Lost on User Recreation

Trigger: A database user is a member of a database role (sys.database_role_members), and the orphaned-user fix (J1) recreates the user without reassigning role membership. Severity: Warning Fix: Capture sys.database_role_members before migrating and re-run ALTER ROLE [rolename] ADD MEMBER [username]; for each membership after fixing orphaned users.

J8 — Explicit Object-Level GRANT/DENY Not Captured in Migration Scripts

Trigger: sys.database_permissions shows explicit (non-role-based) GRANT or DENY statements on objects within the migrated database, and the migration plan only scripts logins/users, not explicit permissions. Severity: Warning Fix: Script sys.database_permissions joined to sys.database_principals and object/schema names before migrating, and replay the explicit GRANT/DENY statements after the database and users exist on the target — explicit grants are not implied by role membership and will be silently lost otherwise.

J9 — Cross-Database Ownership Chain Breaks at Migration Boundary

Trigger: A stored procedure or view in the migrated database references objects in a different database via ownership chaining, and that second database is not in the same migration scope or TRUSTWORTHY/ownership chaining settings differ on the target. Severity: Warning Fix: Identify cross-database ownership chains before migrating (sys.sql_expression_dependencies filtered to cross-database references — capture-security-facts.sql Query 11 collects these per database); either migrate both databases together or replace the chain with an explicit permission grant plus a module signing certificate — do not enable TRUSTWORTHY ON as a substitute, since it is a documented security risk.

Category 3 — Credentials & Secrets

J10 — SQL Server Credential Object Not Migrated

Trigger: Source has one or more sys.credentials entries (used by proxy accounts, CLR, or external data sources), and the migration plan's script set does not include credential recreation. Severity: Critical Fix: CREATE CREDENTIAL cannot be scripted with the underlying secret intact (SQL Server does not expose stored secrets) — re-enter the credential's secret manually on the target using CREATE CREDENTIAL [name] WITH IDENTITY = '', SECRET = '';, sourced from the original secret store, not from the source instance.

J11 — SQL Agent Proxy Account References a Credential Not Yet Created

Trigger: msdb.dbo.sysproxies references a credential by credential_id, and the migration order creates the proxy before the credential exists on the target. Severity: Warning Fix: Sequence the migration script to create the credential (J10) before the proxy account, and re-map credential_id by name rather than by ID, since IDs are not guaranteed to match across instances.

J12 — Linked Server Stored Login Not Migrated

Trigger: Source has sys.linked_logins mappings (impersonation or stored credentials for a linked server), and the migration plan recreates the linked server definition without the stored login mapping. Severity: Warning Fix: Script sp_addlinkedsrvlogin for each mapping captured in sys.linked_logins, supplying the stored password again manually (it is not exposed by any system view) — see /sqlmigration-objects-review for the rest of the linked server definition migration.

Category 4 — Certificates & Keys

J13 — Certificate-Backed Object Migrated Without Its Certificate

Trigger: Source has objects depending on a certificate (Service Broker, certificate-mapped logins, module-signing certificates) per sys.certificates, and the certificate is not in the migration plan's script set. Severity: Critical Fix: BACKUP CERTIFICATE [certname] TO FILE = '' WITH PRIVATE KEY (FILE = '', ENCRYPTION BY PASSWORD = ''); on the source, then CREATE CERTIFICATE ... FROM FILE ... WITH PRIVATE KEY (...) on the target before the dependent objects are created. This excludes TDE certificates — see /sqlencryption-review for the full TDE certificate migration sequence.

J14 — Database Master Key Not Backed Up Before Migration

Trigger: Migrated database has sys.symmetric_keys showing a database master key (name = '##MS_DatabaseMasterKey##'), and no BACKUP MASTER KEY step appears in the migration plan. Severity: Critical Fix: OPEN MASTER KEY DECRYPTION BY PASSWORD = ''; BACKUP MASTER KEY TO FILE = '' ENCRYPTION BY PASSWORD = ''; on the source before migrating, then restore it on the target with RESTORE MASTER KEY FROM FILE = '' DECRYPTION BY PASSWORD = '' ENCRYPTION BY PASSWORD = ''; — see /sqlencryption-review for the full DMK/SMK key hierarchy migration sequence if this database uses Always Encrypted or column-level encryption.

Category 5 — CMS

J15 — Central Management Server Registration Points at Old Instance Name

Trigger: The migration changes the instance name or the listener name the application connects through, and CMS registrations on the CMS host (managed via SSMS Registered Servers, backed internally by msdb.dbo.sysmanagement_shared_registered_servers) still reference the pre-migration name. Severity: Info Fix: Update the CMS registration's server name via the SSMS Registered Servers GUI — this is the Microsoft-documented mechanism and the one to use by default. Unverified: the underlying msdb.dbo.sysmanagement_shared_registered_servers table and a sp_sysmanagement_update_shared_registered_server procedure are referenced in community documentation of CMS internals, but Microsoft Learn does not publicly document this schema or any T-SQL procedure for scripting CMS registration changes — treat any T-SQL-based update to these objects as unsupported and verify against a non-production CMS host before relying on it, or confirm current behavior against the CMS host's actual schema before scripting.

Output Format

## sqlmigration-security-review

### Summary
[2-3 sentences: login count, permission complexity, headline risk]

### Critical Issues
[J-checks with Critical severity — each as: **J# — Name**, evidence, impact, fix]

### Warnings
[J-checks with Warning severity]

### Info
[J-checks with Info severity, if any]

### Passed Checks
[J-checks evaluated and not fired]

### Not Assessed
[J-checks that could not be evaluated because the required input was not provided]

### Login/Permission Migration Script Checklist
[Ordered list of native-tool scripts to run: sp_help_revlogin output, role membership,
explicit grants, credentials, certificates, in dependency order]

---
Analyzed by: [model name] · [date/time]

Output Filters

  • --brief — Summary + Critical Issues only
  • --critical-only — Critical Issues only

Verbose Output (--verbose)

When --verbose is passed, also write output/sqlmigration-security-review/-J/analysis.md (full report) and trace.md (which facts were available, which J-checks were skipped and why).

Notes

  • This skill is strictly offline — it never connects to SQL Server; all checks evaluate pasted

facts or capture-script output.

  • TDE certificates and the full DMK/SMK key hierarchy are sqlencryption-review's domain; J13/J14

cover only the migration-script-sequencing risk, not the encryption posture itself.

  • Dispatched here from /sqlmigration-review for the security-object family — not invoked

standalone for non-migration security review (use sqlencryption-review for that).

Companion Skills

  • sqlmigration-review — parent skill; version/edition/platform compatibility (Y1–Y15)
  • sqlmigration-objects-review — operational objects (Agent jobs, linked servers, Database

Mail) for the rest of the proxy/linked-server definition beyond the stored login (J11/J12)

  • sqlencryption-review — TDE, full DMK/SMK key hierarchy, Always Encrypted, CLE
  • sqlspn-review — SPN/Kerberos delegation for the renamed/relocated instance

Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet — be the first.

Versions

  • v0.1.0 Imported from the upstream source.