[CmdletBinding()] param( [Parameter(Mandatory = $true)] [ValidatePattern('^[a-z0-9][a-z0-9-]*$')] [string]$Project, [string]$OutputDirectory = (Join-Path $env:LOCALAPPDATA 'ITWorx\MCP Hub\credentials'), [switch]$Rotate ) $ErrorActionPreference = 'Stop' New-Item -ItemType Directory -Path $OutputDirectory -Force | Out-Null $path = Join-Path $OutputDirectory "$Project.credential" if ((Test-Path -LiteralPath $path) -and -not $Rotate) { throw "Credential already exists at $path. Use -Rotate only for an intentional rotation." } $bytes = New-Object byte[] 48 [System.Security.Cryptography.RandomNumberGenerator]::Fill($bytes) $value = [Convert]::ToBase64String($bytes).TrimEnd('=').Replace('+', '-').Replace('/', '_') [System.IO.File]::WriteAllText($path, $value, [System.Text.UTF8Encoding]::new($false)) $identity = [System.Security.Principal.WindowsIdentity]::GetCurrent().Name $acl = New-Object System.Security.AccessControl.FileSecurity $acl.SetOwner([System.Security.Principal.NTAccount]::new($identity)) $acl.SetAccessRuleProtection($true, $false) $acl.AddAccessRule([System.Security.AccessControl.FileSystemAccessRule]::new( $identity, [System.Security.AccessControl.FileSystemRights]::FullControl, [System.Security.AccessControl.AccessControlType]::Allow )) Set-Acl -LiteralPath $path -AclObject $acl [Array]::Clear($bytes, 0, $bytes.Length) $value = $null Write-Output $path