IdentityCommand.SecretsManager.psm1
|
function Get-SMApiHeader { <# .SYNOPSIS Returns the Accept header value for a Secrets Manager / SWA API request. .DESCRIPTION Every request in both specs carries an Accept header naming its API version - the stable `application/x.secretsmgr.v2+json`, or the beta `application/x.secretsmgr.v2beta+json` for endpoints the spec marks APIv2 beta. This holds both values so a command names which one it needs rather than hardcoding the media type string. .PARAMETER Version 'V2' for the stable API, 'Beta' for APIv2 beta endpoints. .EXAMPLE Invoke-IDRestMethod -Uri $URI -Method GET -Accept $(Get-SMApiHeader -Version Beta) #> [OutputType([string])] [CmdletBinding()] param( [parameter(Mandatory = $true, Position = 0)] [ValidateSet('V2', 'Beta')] [string]$Version ) switch ($Version) { 'V2' { 'application/x.secretsmgr.v2+json' } 'Beta' { 'application/x.secretsmgr.v2beta+json' } } } # .ExternalHelp IdentityCommand.SecretsManager-help.xml function Add-SMGroupMember { [CmdletBinding(SupportsShouldProcess)] param( [parameter(Mandatory = $true, ValueFromPipelinebyPropertyName = $true)] [ValidateLength(3, 500)] [String]$identifier, [parameter(Mandatory = $true, ValueFromPipelinebyPropertyName = $true)] [Alias('roleId')] [ValidateLength(1, 500)] [String]$id, [parameter(Mandatory = $true, ValueFromPipelinebyPropertyName = $true)] [Alias('roleKind')] [ValidateSet('user', 'workload', 'group')] [String]$kind ) begin { }#begin process { $URI = "$($ISPSSSession.tenant_url)/api/groups/$([uri]::EscapeDataString($identifier))/members" $body = $PSBoundParameters | Get-Parameter -ParametersToRemove identifier if ($PSCmdlet.ShouldProcess($identifier, "Add $kind '$id' as a group member")) { #Send Request $result = Invoke-IDRestMethod -Uri $URI -Method POST -Body ($body | ConvertTo-Json -Depth 4) -Accept $(Get-SMApiHeader -Version Beta) if ($null -ne $result) { $result } } }#process end { }#end } # .ExternalHelp IdentityCommand.SecretsManager-help.xml function Connect-SMTenant { [CmdletBinding(SupportsShouldProcess, DefaultParameterSetName = 'Subdomain')] param( #subdomain [parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true, ParameterSetName = 'Subdomain')] [ValidateNotNullOrEmpty()] [Alias('subdomain')] [String]$tenant_subdomain, #tenant_url [parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true, ParameterSetName = 'URL')] [ValidateNotNullOrEmpty()] [Alias('secretsmgr_url')] [String]$tenant_url, #A Conjur access token obtained some other way, as the exact value the API expects inside #Authorization: Token token="...". Supplying this skips the CyberArk Identity -> Conjur #exchange this command otherwise performs automatically. [parameter(Mandatory = $false)] [SecureString]$ConjurAccessToken ) begin { }#begin process { $UsingSubdomain = $PSCmdlet.ParameterSetName -eq 'Subdomain' if ($UsingSubdomain) { $ServiceUrl = Resolve-ServiceUrl -Service secrets_manager -Subdomain $tenant_subdomain $tenant_url = $ServiceUrl.ServiceUrl } else { #Ensure URL is in expected format - remove trailing slash if provided in Url $tenant_url = $tenant_url -replace '/$', '' } $ISPSSSession.tenant_url = $tenant_url if ($PSBoundParameters.ContainsKey('ConjurAccessToken')) { if ($PSCmdlet.ShouldProcess($tenant_url, 'Set Conjur access token')) { $Token = ConvertTo-InsecureString -SecureString $ConjurAccessToken } } elseif ($PSCmdlet.ShouldProcess($tenant_url, 'Exchange CyberArk Identity session for a Conjur access token')) { #Conjur accepts the same bearer-authenticated WebSession every other companion module #copies from Get-IDSession - no id_token, cookie or CSRF header is required. $ExchangeUri = "$tenant_url/api/authn-oidc/cyberark/conjur/authenticate?set_conjur_cookie=true" $ConjurResponse = Invoke-IDRestMethod -Method POST -URI $ExchangeUri -WebSession (Get-IDSession).WebSession $Token = [Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes(($ConjurResponse | ConvertTo-Json -Compress -Depth 3))) } if ($Token) { #Secrets Manager/SWA authenticate with a Conjur access token, not the CyberArk Identity #bearer session every other companion module shares - building an independent #WebRequestSession here, rather than copying $IDSession.WebSession, keeps this #module's calls from mutating (or being mutated by) that shared session object. $WebSession = [Microsoft.PowerShell.Commands.WebRequestSession]::new() $WebSession.Headers['Authorization'] = "Token token=`"$Token`"" $ISPSSSession.WebSession = $WebSession } }#process end { }#end } # .ExternalHelp IdentityCommand.SecretsManager-help.xml function Get-SMAuthenticator { [CmdletBinding(DefaultParameterSetName = 'List')] param( [parameter(Mandatory = $true, ValueFromPipelinebyPropertyName = $true, ParameterSetName = 'ById')] [ValidateSet('jwt', 'gcp', 'azure', 'aws_iam')] [String]$type, [parameter(Mandatory = $true, ValueFromPipelinebyPropertyName = $true, ParameterSetName = 'ById')] [ValidateLength(1, 60)] [String]$name ) begin { }#begin process { if ($PSCmdlet.ParameterSetName -eq 'ById') { $URI = "$($ISPSSSession.tenant_url)/api/authenticators/$type/$([uri]::EscapeDataString($name))" $result = Invoke-IDRestMethod -Uri $URI -Method GET -Accept $(Get-SMApiHeader -Version Beta) if ($null -ne $result) { $result } } else { $URI = "$($ISPSSSession.tenant_url)/api/authenticators" $result = Invoke-IDRestMethod -Uri $URI -Method GET -Accept $(Get-SMApiHeader -Version Beta) if ($null -ne $result) { $result.authenticators } } }#process end { }#end } # .ExternalHelp IdentityCommand.SecretsManager-help.xml function Get-SMCABundle { [CmdletBinding()] param( [parameter(Mandatory = $true, ValueFromPipelinebyPropertyName = $true)] [Alias('name')] [String]$trustDomainName, [parameter(Mandatory = $false, ValueFromPipelinebyPropertyName = $true)] [ValidateSet('der', 'pem')] [String]$format ) begin { }#begin process { $URI = "$($ISPSSSession.tenant_url)/api/swa/trust-domains/$([uri]::EscapeDataString($trustDomainName))/.well-known/ca-bundles" if ($PSBoundParameters.ContainsKey('format')) { $URI = Add-QueryString -URI $URI -Parameter @{ format = $format } } #This endpoint is public - no authentication or Accept header is required. $result = Invoke-IDRestMethod -Uri $URI -Method GET if ($null -ne $result) { $result } }#process end { }#end } # .ExternalHelp IdentityCommand.SecretsManager-help.xml function Get-SMIssuer { [CmdletBinding(DefaultParameterSetName = 'List')] param( [parameter(Mandatory = $true, ValueFromPipelinebyPropertyName = $true, ParameterSetName = 'ById')] [Alias('id')] [String]$issuerName ) begin { }#begin process { if ($PSCmdlet.ParameterSetName -eq 'ById') { $URI = "$($ISPSSSession.tenant_url)/api/issuers/$([uri]::EscapeDataString($issuerName))" #Send Request $result = Invoke-IDRestMethod -Uri $URI -Method GET -Accept $(Get-SMApiHeader -Version V2) if ($null -ne $result) { $result } } else { $URI = "$($ISPSSSession.tenant_url)/api/issuers/conjur" #Send Request $result = Invoke-IDRestMethod -Uri $URI -Method GET -Accept $(Get-SMApiHeader -Version V2) if ($null -ne $result) { $result.issuers } } }#process end { }#end } # .ExternalHelp IdentityCommand.SecretsManager-help.xml function Get-SMJwks { [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseSingularNouns', '', Justification = 'JWKS is an acronym (JSON Web Key Set), not a plural noun')] [CmdletBinding()] param( [parameter(Mandatory = $true, ValueFromPipelinebyPropertyName = $true)] [Alias('name')] [String]$trustDomainName ) begin { }#begin process { $URI = "$($ISPSSSession.tenant_url)/api/swa/trust-domains/$([uri]::EscapeDataString($trustDomainName))/.well-known/jwks" #This endpoint is public - no authentication is required. Returned whole (not unwrapped to #just .keys) since it is a discovery document, not a list resource. $result = Invoke-IDRestMethod -Uri $URI -Method GET if ($null -ne $result) { $result } }#process end { }#end } # .ExternalHelp IdentityCommand.SecretsManager-help.xml function Get-SMModuleData { [CmdletBinding()] param() begin { }#begin process { #Calculate the time elapsed since the start of the session and include in return data if ($null -ne $ISPSSSession.StartTime) { $ISPSSSession.ElapsedTime = '{0:HH:mm:ss}' -f ([datetime]$($(Get-Date) - $($ISPSSSession.StartTime)).Ticks) } else { $ISPSSSession.ElapsedTime = $null } #Deep Copy the $ISPSSSession session object and return as IdCmd Session type. Get-SessionClone -InputObject $ISPSSSession | Add-CustomType -Type IdCmd.Session }#process end { }#end } # .ExternalHelp IdentityCommand.SecretsManager-help.xml function Get-SMNodeGroup { [CmdletBinding(DefaultParameterSetName = 'List')] param( [parameter(Mandatory = $true, ValueFromPipelinebyPropertyName = $true)] [Alias('name')] [String]$trustDomainName, [parameter(Mandatory = $true, ValueFromPipelinebyPropertyName = $true)] [String]$serverGroupName, [parameter(Mandatory = $true, ValueFromPipelinebyPropertyName = $true, ParameterSetName = 'ByName')] [String]$nodeGroupName, [parameter(Mandatory = $false, ValueFromPipelinebyPropertyName = $true, ParameterSetName = 'List')] [ValidateRange(1, 1000)] [int]$limit, [parameter(Mandatory = $false, ValueFromPipelinebyPropertyName = $true, ParameterSetName = 'List')] [ValidateRange(0, [int]::MaxValue)] [int]$offset ) begin { }#begin process { $BaseURI = "$($ISPSSSession.tenant_url)/api/swa/trust-domains/$([uri]::EscapeDataString($trustDomainName))/server-groups/$([uri]::EscapeDataString($serverGroupName))/node-groups" if ($PSCmdlet.ParameterSetName -eq 'ByName') { $URI = "$BaseURI/$([uri]::EscapeDataString($nodeGroupName))" $result = Invoke-IDRestMethod -Uri $URI -Method GET -Accept $(Get-SMApiHeader -Version V2) if ($null -ne $result) { $result } } else { $URI = Add-QueryString -URI $BaseURI -Parameter ($PSBoundParameters | Get-Parameter -ParametersToRemove trustDomainName, serverGroupName) $result = Invoke-IDRestMethod -Uri $URI -Method GET -Accept $(Get-SMApiHeader -Version V2) if ($null -ne $result) { $result.node_groups } } }#process end { }#end } # .ExternalHelp IdentityCommand.SecretsManager-help.xml function Get-SMOpenIDConfiguration { [CmdletBinding()] param( [parameter(Mandatory = $true, ValueFromPipelinebyPropertyName = $true)] [Alias('name')] [String]$trustDomainName ) begin { }#begin process { $URI = "$($ISPSSSession.tenant_url)/api/swa/trust-domains/$([uri]::EscapeDataString($trustDomainName))/.well-known/openid-configuration" #This endpoint is public - no authentication is required. $result = Invoke-IDRestMethod -Uri $URI -Method GET if ($null -ne $result) { $result } }#process end { }#end } # .ExternalHelp IdentityCommand.SecretsManager-help.xml function Get-SMSecretValue { [CmdletBinding()] param( [parameter(Mandatory = $true, ValueFromPipelinebyPropertyName = $true)] [Alias('ids')] [ValidateCount(1, 250)] [String[]]$id, #Base64-encode every returned secret value. [parameter(Mandatory = $false, ValueFromPipelinebyPropertyName = $true)] [switch]$encode_values ) begin { }#begin process { $URI = "$($ISPSSSession.tenant_url)/api/secrets/values" if ($encode_values.IsPresent) { $URI = Add-QueryString -URI $URI -Parameter @{ encode_values = 'base64' } } $body = @{ ids = @($id) } #Send Request $result = Invoke-IDRestMethod -Uri $URI -Method POST -Body ($body | ConvertTo-Json -Depth 3) -Accept $(Get-SMApiHeader -Version Beta) if ($null -ne $result) { $result.secrets } }#process end { }#end } # .ExternalHelp IdentityCommand.SecretsManager-help.xml function Get-SMServer { [CmdletBinding(DefaultParameterSetName = 'List')] param( [parameter(Mandatory = $true, ValueFromPipelinebyPropertyName = $true)] [Alias('name')] [String]$trustDomainName, [parameter(Mandatory = $true, ValueFromPipelinebyPropertyName = $true)] [String]$serverGroupName, [parameter(Mandatory = $true, ValueFromPipelinebyPropertyName = $true, ParameterSetName = 'ByName')] [String]$serverName, [parameter(Mandatory = $false, ValueFromPipelinebyPropertyName = $true, ParameterSetName = 'List')] [ValidateRange(1, 1000)] [int]$limit, [parameter(Mandatory = $false, ValueFromPipelinebyPropertyName = $true, ParameterSetName = 'List')] [ValidateRange(0, [int]::MaxValue)] [int]$offset ) begin { }#begin process { $BaseURI = "$($ISPSSSession.tenant_url)/api/swa/trust-domains/$([uri]::EscapeDataString($trustDomainName))/server-groups/$([uri]::EscapeDataString($serverGroupName))/components" if ($PSCmdlet.ParameterSetName -eq 'ByName') { $URI = "$BaseURI/$([uri]::EscapeDataString($serverName))" $result = Invoke-IDRestMethod -Uri $URI -Method GET -Accept $(Get-SMApiHeader -Version V2) if ($null -ne $result) { $result } } else { $URI = Add-QueryString -URI $BaseURI -Parameter ($PSBoundParameters | Get-Parameter -ParametersToRemove trustDomainName, serverGroupName) $result = Invoke-IDRestMethod -Uri $URI -Method GET -Accept $(Get-SMApiHeader -Version V2) if ($null -ne $result) { $result.components } } }#process end { }#end } # .ExternalHelp IdentityCommand.SecretsManager-help.xml function Get-SMServerGroup { [CmdletBinding(DefaultParameterSetName = 'List')] param( [parameter(Mandatory = $true, ValueFromPipelinebyPropertyName = $true)] [Alias('name')] [String]$trustDomainName, [parameter(Mandatory = $true, ValueFromPipelinebyPropertyName = $true, ParameterSetName = 'ByName')] [String]$serverGroupName, [parameter(Mandatory = $false, ValueFromPipelinebyPropertyName = $true, ParameterSetName = 'List')] [ValidateRange(1, 1000)] [int]$limit, [parameter(Mandatory = $false, ValueFromPipelinebyPropertyName = $true, ParameterSetName = 'List')] [ValidateRange(0, [int]::MaxValue)] [int]$offset ) begin { }#begin process { $BaseURI = "$($ISPSSSession.tenant_url)/api/swa/trust-domains/$([uri]::EscapeDataString($trustDomainName))/server-groups" if ($PSCmdlet.ParameterSetName -eq 'ByName') { $URI = "$BaseURI/$([uri]::EscapeDataString($serverGroupName))" $result = Invoke-IDRestMethod -Uri $URI -Method GET -Accept $(Get-SMApiHeader -Version V2) if ($null -ne $result) { $result } } else { $URI = Add-QueryString -URI $BaseURI -Parameter ($PSBoundParameters | Get-Parameter -ParametersToRemove trustDomainName) $result = Invoke-IDRestMethod -Uri $URI -Method GET -Accept $(Get-SMApiHeader -Version V2) if ($null -ne $result) { $result.server_groups } } }#process end { }#end } # .ExternalHelp IdentityCommand.SecretsManager-help.xml function Get-SMTrustDomain { [CmdletBinding(DefaultParameterSetName = 'List')] param( [parameter(Mandatory = $true, ValueFromPipelinebyPropertyName = $true, ParameterSetName = 'ByName')] [Alias('name')] [String]$trustDomainName, #The response reports only the count of items in this page, not an overall total or a next #offset - so this command cannot page automatically. Increase -offset yourself until a page #comes back with fewer than -limit trust domains. [parameter(Mandatory = $false, ValueFromPipelinebyPropertyName = $true, ParameterSetName = 'List')] [ValidateRange(1, 1000)] [int]$limit, [parameter(Mandatory = $false, ValueFromPipelinebyPropertyName = $true, ParameterSetName = 'List')] [ValidateRange(0, [int]::MaxValue)] [int]$offset ) begin { }#begin process { if ($PSCmdlet.ParameterSetName -eq 'ByName') { $URI = "$($ISPSSSession.tenant_url)/api/swa/trust-domains/$([uri]::EscapeDataString($trustDomainName))" $result = Invoke-IDRestMethod -Uri $URI -Method GET -Accept $(Get-SMApiHeader -Version V2) if ($null -ne $result) { $result } } else { $URI = "$($ISPSSSession.tenant_url)/api/swa/trust-domains" $URI = Add-QueryString -URI $URI -Parameter ($PSBoundParameters | Get-Parameter) $result = Invoke-IDRestMethod -Uri $URI -Method GET -Accept $(Get-SMApiHeader -Version V2) if ($null -ne $result) { $result.trust_domains } } }#process end { }#end } # .ExternalHelp IdentityCommand.SecretsManager-help.xml function New-SMAuthenticator { [CmdletBinding(SupportsShouldProcess)] param( [parameter(Mandatory = $true, ValueFromPipelinebyPropertyName = $true)] [ValidateSet('jwt', 'aws_iam')] [String]$type, [parameter(Mandatory = $false, ValueFromPipelinebyPropertyName = $true)] [ValidateSet('gitlab', 'github_actions', 'kubernetes', 'jenkins')] [String]$subtype, [parameter(Mandatory = $true, ValueFromPipelinebyPropertyName = $true)] [ValidateLength(1, 60)] [String]$name, [parameter(Mandatory = $false, ValueFromPipelinebyPropertyName = $true)] [bool]$enabled, [parameter(Mandatory = $false, ValueFromPipelinebyPropertyName = $true)] [String]$ownerId, [parameter(Mandatory = $false, ValueFromPipelinebyPropertyName = $true)] [ValidateSet('user', 'workload', 'group')] [String]$ownerKind, [parameter(Mandatory = $false, ValueFromPipelinebyPropertyName = $true)] [String]$ca_cert, [parameter(Mandatory = $false, ValueFromPipelinebyPropertyName = $true)] [String]$audience, [parameter(Mandatory = $false, ValueFromPipelinebyPropertyName = $true)] [String]$jwks_uri, [parameter(Mandatory = $false, ValueFromPipelinebyPropertyName = $true)] [hashtable]$public_keys, [parameter(Mandatory = $false, ValueFromPipelinebyPropertyName = $true)] [String]$issuer, [parameter(Mandatory = $false, ValueFromPipelinebyPropertyName = $true)] [hashtable]$claim_aliases, [parameter(Mandatory = $false, ValueFromPipelinebyPropertyName = $true)] [String[]]$enforced_claims, [parameter(Mandatory = $false, ValueFromPipelinebyPropertyName = $true)] [String]$identity_path, [parameter(Mandatory = $false, ValueFromPipelinebyPropertyName = $true)] [String]$token_app_property, [parameter(Mandatory = $false, ValueFromPipelinebyPropertyName = $true)] [hashtable]$annotations ) begin { }#begin process { $URI = "$($ISPSSSession.tenant_url)/api/authenticators" $body = [ordered]@{ type = $type; name = $name } foreach ($p in 'subtype', 'enabled', 'annotations') { if ($PSBoundParameters.ContainsKey($p)) { $body[$p] = $PSBoundParameters[$p] } } if ($PSBoundParameters.ContainsKey('ownerId')) { $body['owner'] = [ordered]@{ id = $ownerId; kind = $ownerKind } } $Data = [ordered]@{} foreach ($p in 'ca_cert', 'audience', 'jwks_uri', 'public_keys', 'issuer') { if ($PSBoundParameters.ContainsKey($p)) { $Data[$p] = $PSBoundParameters[$p] } } $Identity = [ordered]@{} foreach ($p in 'claim_aliases', 'enforced_claims', 'identity_path', 'token_app_property') { if ($PSBoundParameters.ContainsKey($p)) { $Identity[$p] = $PSBoundParameters[$p] } } if ($Identity.Keys.Count -gt 0) { $Data['identity'] = $Identity } if ($Data.Keys.Count -gt 0) { $body['data'] = $Data } if ($PSCmdlet.ShouldProcess($name, "Create $type authenticator")) { $result = Invoke-IDRestMethod -Uri $URI -Method POST -Body ($body | ConvertTo-Json -Depth 6) -Accept $(Get-SMApiHeader -Version Beta) if ($null -ne $result) { $result } } }#process end { }#end } # .ExternalHelp IdentityCommand.SecretsManager-help.xml function New-SMIssuedCertificate { [CmdletBinding(SupportsShouldProcess)] param( [parameter(Mandatory = $true, ValueFromPipelinebyPropertyName = $true)] [String]$issuerName, [parameter(Mandatory = $true, ValueFromPipelinebyPropertyName = $true)] [ValidateLength(1, 64)] [String]$common_name, [parameter(Mandatory = $false, ValueFromPipelinebyPropertyName = $true)] [String]$organization, [parameter(Mandatory = $false, ValueFromPipelinebyPropertyName = $true)] [String[]]$org_units, [parameter(Mandatory = $false, ValueFromPipelinebyPropertyName = $true)] [String]$locality, [parameter(Mandatory = $false, ValueFromPipelinebyPropertyName = $true)] [String]$state, [parameter(Mandatory = $false, ValueFromPipelinebyPropertyName = $true)] [ValidateLength(2, 2)] [String]$country, [parameter(Mandatory = $false, ValueFromPipelinebyPropertyName = $true)] [ValidateSet('RSA_2048', 'RSA_3072', 'RSA_4096', 'EC_P256', 'EC_P384', 'EC_P521', 'EC_ED25519')] [String]$key_type, [parameter(Mandatory = $false, ValueFromPipelinebyPropertyName = $true)] [String[]]$dns_names, [parameter(Mandatory = $false, ValueFromPipelinebyPropertyName = $true)] [String[]]$ip_addresses, [parameter(Mandatory = $false, ValueFromPipelinebyPropertyName = $true)] [String[]]$email_addresses, [parameter(Mandatory = $false, ValueFromPipelinebyPropertyName = $true)] [String[]]$uris, #ISO 8601 duration, e.g. P30D [parameter(Mandatory = $false, ValueFromPipelinebyPropertyName = $true)] [String]$ttl, [parameter(Mandatory = $false, ValueFromPipelinebyPropertyName = $true)] [String]$zone, [parameter(Mandatory = $false, ValueFromPipelinebyPropertyName = $true)] [bool]$ignore_storage ) begin { }#begin process { $URI = "$($ISPSSSession.tenant_url)/api/issuers/$([uri]::EscapeDataString($issuerName))/issue" $Subject = [ordered]@{ common_name = $common_name } foreach ($p in 'organization', 'org_units', 'locality', 'state', 'country') { if ($PSBoundParameters.ContainsKey($p)) { $Subject[$p] = $PSBoundParameters[$p] } } $body = [ordered]@{ subject = $Subject } $AltNames = [ordered]@{} foreach ($p in 'dns_names', 'ip_addresses', 'email_addresses', 'uris') { if ($PSBoundParameters.ContainsKey($p)) { $AltNames[$p] = @($PSBoundParameters[$p]) } } if ($AltNames.Keys.Count -gt 0) { $body['alt_names'] = $AltNames } foreach ($p in 'key_type', 'ttl', 'zone', 'ignore_storage') { if ($PSBoundParameters.ContainsKey($p)) { $body[$p] = $PSBoundParameters[$p] } } if ($PSCmdlet.ShouldProcess($issuerName, "Issue certificate for '$common_name'")) { #The response can carry a private_key - convert to UTF8 bytes rather than a String $result = Invoke-IDRestMethod -Uri $URI -Method POST -Body ($body | ConvertTo-SecretBody -Depth 6) -Accept $(Get-SMApiHeader -Version Beta) if ($null -ne $result) { $result } } }#process end { }#end } # .ExternalHelp IdentityCommand.SecretsManager-help.xml function New-SMIssuer { [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidUsingPlainTextForPassword', 'password_secret_ref', Justification = 'Reference to an existing stored secret, not the secret itself')] [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidUsingUsernameAndPasswordParams', '', Justification = 'user_id_secret_ref/password_secret_ref are references to existing stored secrets, not credentials')] [CmdletBinding(SupportsShouldProcess, DefaultParameterSetName = 'AWS')] param( [parameter(Mandatory = $true, ValueFromPipelinebyPropertyName = $true)] [Alias('issuerName')] [ValidateLength(1, 60)] [String]$id, [parameter(Mandatory = $false, ValueFromPipelinebyPropertyName = $true)] [ValidateRange(900, 43200)] [int]$max_ttl, #--- AWS --- [parameter(Mandatory = $true, ParameterSetName = 'AWS')] [ValidateLength(16, 16)] [String]$access_key_id, [parameter(Mandatory = $true, ParameterSetName = 'AWS')] [SecureString]$secret_access_key, #--- GCP --- [parameter(Mandatory = $true, ParameterSetName = 'GCP')] [ValidateLength(6, 500)] [String]$service_account_key_secret_ref, [parameter(Mandatory = $false, ParameterSetName = 'GCP')] [String[]]$access_token_permitted_scope, #--- PKI_VENAFI_SAAS --- [parameter(Mandatory = $true, ParameterSetName = 'VenafiSaaS')] [String]$service_account_token_url, [parameter(Mandatory = $true, ParameterSetName = 'VenafiSaaS')] [String]$user_id_secret_ref, [parameter(Mandatory = $true, ParameterSetName = 'VenafiSaaS')] [String]$password_secret_ref, [parameter(Mandatory = $true, ParameterSetName = 'VenafiSaaS')] [String]$default_zone, [parameter(Mandatory = $true, ParameterSetName = 'VenafiSaaS')] [String[]]$allowed_zones ) begin { }#begin process { $URI = "$($ISPSSSession.tenant_url)/api/issuers/conjur" $data = switch ($PSCmdlet.ParameterSetName) { 'AWS' { [ordered]@{ access_key_id = $access_key_id secret_access_key = $(ConvertTo-InsecureString -SecureString $secret_access_key) } } 'GCP' { $GcpData = [ordered]@{ service_account_key_secret_ref = [ordered]@{ id = $service_account_key_secret_ref } } if ($PSBoundParameters.ContainsKey('access_token_permitted_scope')) { $GcpData['access_token_permitted_scope'] = @($access_token_permitted_scope) } $GcpData } 'VenafiSaaS' { [ordered]@{ service_account_token_url = $service_account_token_url identity_user_details = [ordered]@{ user_id_secret_ref = [ordered]@{ id = $user_id_secret_ref } password_secret_ref = [ordered]@{ id = $password_secret_ref } } default_zone = $default_zone allowed_zones = @($allowed_zones) } } } $Type = switch ($PSCmdlet.ParameterSetName) { 'AWS' { 'AWS' } 'GCP' { 'GCP' } 'VenafiSaaS' { 'PKI_VENAFI_SAAS' } } $body = [ordered]@{ id = $id; type = $Type; data = $data } if ($PSBoundParameters.ContainsKey('max_ttl')) { $body['max_ttl'] = $max_ttl } if ($PSCmdlet.ShouldProcess($id, 'Create Secrets Manager issuer')) { #Secrets carried in -data (AWS secret_access_key) are decoded above, so the body travels #as UTF8 bytes rather than a String. $result = Invoke-IDRestMethod -Uri $URI -Method POST -Body ($body | ConvertTo-SecretBody -Depth 6) -Accept $(Get-SMApiHeader -Version V2) if ($null -ne $result) { $result } } }#process end { }#end } # .ExternalHelp IdentityCommand.SecretsManager-help.xml function New-SMNodeGroup { [CmdletBinding(SupportsShouldProcess)] param( [parameter(Mandatory = $true, ValueFromPipelinebyPropertyName = $true)] [String]$trustDomainName, [parameter(Mandatory = $true, ValueFromPipelinebyPropertyName = $true)] [String]$serverGroupName, [parameter(Mandatory = $true, ValueFromPipelinebyPropertyName = $true)] [Alias('nodeGroupName')] [ValidateLength(1, 60)] [String]$Name, [parameter(Mandatory = $true, ValueFromPipelinebyPropertyName = $true)] [ValidateSet('kubernetes', 'unix')] [String]$workload_type, [parameter(Mandatory = $false, ValueFromPipelinebyPropertyName = $true)] [String]$description, [parameter(Mandatory = $false, ValueFromPipelinebyPropertyName = $true)] [String]$spiffe_id_template, [parameter(Mandatory = $false, ValueFromPipelinebyPropertyName = $true)] [String[]]$workload_registration_policies ) begin { }#begin process { $URI = "$($ISPSSSession.tenant_url)/api/swa/trust-domains/$([uri]::EscapeDataString($trustDomainName))/server-groups/$([uri]::EscapeDataString($serverGroupName))/node-groups" $body = [ordered]@{ name = $Name; workload_type = $workload_type } if ($PSBoundParameters.ContainsKey('description')) { $body['description'] = $description } $WorkloadConfig = [ordered]@{} if ($PSBoundParameters.ContainsKey('spiffe_id_template')) { $WorkloadConfig['spiffe_id_template'] = $spiffe_id_template } if ($PSBoundParameters.ContainsKey('workload_registration_policies')) { $WorkloadConfig['workload_registration_policies'] = @($workload_registration_policies) } if ($WorkloadConfig.Keys.Count -gt 0) { $body['workload_configuration'] = $WorkloadConfig } if ($PSCmdlet.ShouldProcess($Name, 'Create SWA node group')) { $result = Invoke-IDRestMethod -Uri $URI -Method POST -Body ($body | ConvertTo-Json -Depth 5) -Accept $(Get-SMApiHeader -Version V2) if ($null -ne $result) { $result } } }#process end { }#end } # .ExternalHelp IdentityCommand.SecretsManager-help.xml function New-SMServer { [CmdletBinding(SupportsShouldProcess)] param( [parameter(Mandatory = $true, ValueFromPipelinebyPropertyName = $true)] [String]$trustDomainName, [parameter(Mandatory = $true, ValueFromPipelinebyPropertyName = $true)] [String]$serverGroupName, [parameter(Mandatory = $true, ValueFromPipelinebyPropertyName = $true)] [Alias('serverName')] [ValidateLength(1, 51)] [String]$Name, #Subject claim value from the workload JWT identifying this server. [parameter(Mandatory = $true, ValueFromPipelinebyPropertyName = $true)] [String]$sub, [parameter(Mandatory = $false, ValueFromPipelinebyPropertyName = $true)] [String]$ca_cert, [parameter(Mandatory = $false, ValueFromPipelinebyPropertyName = $true)] [String]$audience, [parameter(Mandatory = $false, ValueFromPipelinebyPropertyName = $true)] [String]$jwks_uri, [parameter(Mandatory = $false, ValueFromPipelinebyPropertyName = $true)] [hashtable]$public_keys, [parameter(Mandatory = $false, ValueFromPipelinebyPropertyName = $true)] [String]$issuer, [parameter(Mandatory = $false, ValueFromPipelinebyPropertyName = $true)] [hashtable]$claim_aliases, [parameter(Mandatory = $false, ValueFromPipelinebyPropertyName = $true)] [String[]]$enforced_claims, [parameter(Mandatory = $false, ValueFromPipelinebyPropertyName = $true)] [String]$identity_path, [parameter(Mandatory = $false, ValueFromPipelinebyPropertyName = $true)] [String]$token_app_property ) begin { }#begin process { $URI = "$($ISPSSSession.tenant_url)/api/swa/trust-domains/$([uri]::EscapeDataString($trustDomainName))/server-groups/$([uri]::EscapeDataString($serverGroupName))/components" $Data = [ordered]@{ sub = $sub } foreach ($p in 'ca_cert', 'audience', 'jwks_uri', 'public_keys', 'issuer') { if ($PSBoundParameters.ContainsKey($p)) { $Data[$p] = $PSBoundParameters[$p] } } $Identity = [ordered]@{} foreach ($p in 'claim_aliases', 'enforced_claims', 'identity_path', 'token_app_property') { if ($PSBoundParameters.ContainsKey($p)) { $Identity[$p] = $PSBoundParameters[$p] } } if ($Identity.Keys.Count -gt 0) { $Data['identity'] = $Identity } $body = [ordered]@{ name = $Name authentication = [ordered]@{ type = 'JWT' data = $Data } } if ($PSCmdlet.ShouldProcess($Name, 'Register SWA server')) { $result = Invoke-IDRestMethod -Uri $URI -Method POST -Body ($body | ConvertTo-Json -Depth 6) -Accept $(Get-SMApiHeader -Version V2) if ($null -ne $result) { $result } } }#process end { }#end } # .ExternalHelp IdentityCommand.SecretsManager-help.xml function New-SMServerGroup { [CmdletBinding(SupportsShouldProcess)] param( [parameter(Mandatory = $true, ValueFromPipelinebyPropertyName = $true)] [String]$trustDomainName, [parameter(Mandatory = $true, ValueFromPipelinebyPropertyName = $true)] [Alias('serverGroupName')] [ValidateLength(1, 60)] [String]$Name, [parameter(Mandatory = $false, ValueFromPipelinebyPropertyName = $true)] [ValidateLength(0, 1024)] [String]$description, [parameter(Mandatory = $false, ValueFromPipelinebyPropertyName = $true)] [String[]]$gcp_service_account_allowed_project_ids, [parameter(Mandatory = $false, ValueFromPipelinebyPropertyName = $true)] [String[]]$gcp_service_account_audiences, [parameter(Mandatory = $false, ValueFromPipelinebyPropertyName = $true)] [String]$aws_iid_assume_role, [parameter(Mandatory = $false, ValueFromPipelinebyPropertyName = $true)] [ValidateSet('aws', 'aws-cn', 'aws-us-gov')] [String]$aws_iid_partition, [parameter(Mandatory = $false, ValueFromPipelinebyPropertyName = $true)] [String]$aws_iid_management_account_id, [parameter(Mandatory = $false, ValueFromPipelinebyPropertyName = $true)] [String]$aws_iid_management_account_region, [parameter(Mandatory = $false, ValueFromPipelinebyPropertyName = $true)] [String]$aws_iid_assume_org_role, [parameter(Mandatory = $false, ValueFromPipelinebyPropertyName = $true)] [String]$aws_iid_org_account_map_ttl, [parameter(Mandatory = $false, ValueFromPipelinebyPropertyName = $true)] [String]$aws_iid_account_list_file ) begin { }#begin process { $URI = "$($ISPSSSession.tenant_url)/api/swa/trust-domains/$([uri]::EscapeDataString($trustDomainName))/server-groups" $body = [ordered]@{ name = $Name } if ($PSBoundParameters.ContainsKey('description')) { $body['description'] = $description } $Attestation = [ordered]@{} if ($PSBoundParameters.ContainsKey('gcp_service_account_allowed_project_ids')) { $Gcp = [ordered]@{ allowed_project_ids = @($gcp_service_account_allowed_project_ids) } if ($PSBoundParameters.ContainsKey('gcp_service_account_audiences')) { $Gcp['audiences'] = @($gcp_service_account_audiences) } $Attestation['gcp_service_account'] = $Gcp } $AwsIidParams = 'aws_iid_assume_role', 'aws_iid_partition' if (($AwsIidParams | Where-Object { $PSBoundParameters.ContainsKey($_) }) -or ($PSBoundParameters.ContainsKey('aws_iid_management_account_id'))) { $AwsIid = [ordered]@{} if ($PSBoundParameters.ContainsKey('aws_iid_assume_role')) { $AwsIid['assume_role'] = $aws_iid_assume_role } if ($PSBoundParameters.ContainsKey('aws_iid_partition')) { $AwsIid['partition'] = $aws_iid_partition } $VerifyOrg = [ordered]@{} foreach ($p in 'management_account_id', 'management_account_region', 'assume_org_role', 'org_account_map_ttl', 'account_list_file') { $ParamName = "aws_iid_$p" if ($PSBoundParameters.ContainsKey($ParamName)) { $VerifyOrg[$p] = $PSBoundParameters[$ParamName] } } if ($VerifyOrg.Keys.Count -gt 0) { $AwsIid['verify_organization'] = $VerifyOrg } $Attestation['aws_iid'] = $AwsIid } if ($Attestation.Keys.Count -gt 0) { $body['attestation'] = $Attestation } if ($PSCmdlet.ShouldProcess($Name, 'Create SWA server group')) { $result = Invoke-IDRestMethod -Uri $URI -Method POST -Body ($body | ConvertTo-Json -Depth 6) -Accept $(Get-SMApiHeader -Version V2) if ($null -ne $result) { $result } } }#process end { }#end } # .ExternalHelp IdentityCommand.SecretsManager-help.xml function New-SMSignedCertificate { [CmdletBinding(SupportsShouldProcess)] param( [parameter(Mandatory = $true, ValueFromPipelinebyPropertyName = $true)] [String]$issuerName, [parameter(Mandatory = $true, ValueFromPipelinebyPropertyName = $true)] [ValidateNotNullOrEmpty()] [String]$csr, [parameter(Mandatory = $false, ValueFromPipelinebyPropertyName = $true)] [String]$zone, #ISO 8601 duration, e.g. P30D [parameter(Mandatory = $false, ValueFromPipelinebyPropertyName = $true)] [String]$ttl ) begin { }#begin process { $URI = "$($ISPSSSession.tenant_url)/api/issuers/$([uri]::EscapeDataString($issuerName))/sign" $body = $PSBoundParameters | Get-Parameter -ParametersToRemove issuerName if ($PSCmdlet.ShouldProcess($issuerName, 'Sign certificate from CSR')) { $result = Invoke-IDRestMethod -Uri $URI -Method POST -Body ($body | ConvertTo-Json -Depth 4) -Accept $(Get-SMApiHeader -Version Beta) if ($null -ne $result) { $result } } }#process end { }#end } # .ExternalHelp IdentityCommand.SecretsManager-help.xml function New-SMTrustDomain { [CmdletBinding(SupportsShouldProcess)] param( [parameter(Mandatory = $true, ValueFromPipelinebyPropertyName = $true)] [ValidateLength(1, 60)] [String]$name, [parameter(Mandatory = $false, ValueFromPipelinebyPropertyName = $true)] [ValidateSet('EC_P256', 'EC_P384', 'EC_P521', 'RSA_2048', 'RSA_4096')] [String]$signing_key_type, [parameter(Mandatory = $false, ValueFromPipelinebyPropertyName = $true)] [ValidateSet('ES256', 'ES384', 'ES512', 'RS256', 'RS384', 'RS512')] [String]$signature_algorithm, [parameter(Mandatory = $false, ValueFromPipelinebyPropertyName = $true)] [ValidateRange(3600, 2592000)] [int]$signing_key_ttl, [parameter(Mandatory = $false, ValueFromPipelinebyPropertyName = $true)] [ValidateRange(60, 86400)] [int]$token_ttl, [parameter(Mandatory = $false, ValueFromPipelinebyPropertyName = $true)] [ValidateRange(600, 86400)] [int]$workload_ttl ) begin { }#begin process { $URI = "$($ISPSSSession.tenant_url)/api/swa/trust-domains" $body = [ordered]@{ name = $name } $Jwt = [ordered]@{} foreach ($p in 'signing_key_type', 'signature_algorithm', 'signing_key_ttl', 'token_ttl') { if ($PSBoundParameters.ContainsKey($p)) { $Jwt[$p] = $PSBoundParameters[$p] } } if ($Jwt.Keys.Count -gt 0) { $body['jwt'] = $Jwt } if ($PSBoundParameters.ContainsKey('workload_ttl')) { $body['x509'] = [ordered]@{ workload_ttl = $workload_ttl } } if ($PSCmdlet.ShouldProcess($name, 'Register SWA trust domain')) { $result = Invoke-IDRestMethod -Uri $URI -Method POST -Body ($body | ConvertTo-Json -Depth 4) -Accept $(Get-SMApiHeader -Version V2) if ($null -ne $result) { $result } } }#process end { }#end } # .ExternalHelp IdentityCommand.SecretsManager-help.xml function Remove-SMAuthenticator { [CmdletBinding(SupportsShouldProcess)] param( #Not applicable to gcp authenticators, per the service. [parameter(Mandatory = $true, ValueFromPipelinebyPropertyName = $true)] [ValidateSet('jwt', 'azure', 'aws_iam')] [String]$type, [parameter(Mandatory = $true, ValueFromPipelinebyPropertyName = $true)] [ValidateLength(1, 60)] [String]$name ) begin { }#begin process { $URI = "$($ISPSSSession.tenant_url)/api/authenticators/$type/$([uri]::EscapeDataString($name))" if ($PSCmdlet.ShouldProcess($name, "Delete $type authenticator")) { Invoke-IDRestMethod -Uri $URI -Method DELETE -Accept $(Get-SMApiHeader -Version Beta) } }#process end { }#end } # .ExternalHelp IdentityCommand.SecretsManager-help.xml function Remove-SMGroupMember { [CmdletBinding(SupportsShouldProcess)] param( [parameter(Mandatory = $true, ValueFromPipelinebyPropertyName = $true)] [ValidateLength(3, 500)] [String]$identifier, [parameter(Mandatory = $true, ValueFromPipelinebyPropertyName = $true)] [Alias('roleId')] [ValidateLength(1, 1000)] [String]$id, [parameter(Mandatory = $true, ValueFromPipelinebyPropertyName = $true)] [Alias('roleKind')] [ValidateSet('workload', 'user', 'group')] [String]$kind ) begin { }#begin process { $URI = "$($ISPSSSession.tenant_url)/api/groups/$([uri]::EscapeDataString($identifier))/members/$kind/$([uri]::EscapeDataString($id))" if ($PSCmdlet.ShouldProcess($identifier, "Remove $kind '$id' as a group member")) { #Send Request Invoke-IDRestMethod -Uri $URI -Method DELETE -Accept $(Get-SMApiHeader -Version Beta) } }#process end { }#end } # .ExternalHelp IdentityCommand.SecretsManager-help.xml function Remove-SMIssuer { [CmdletBinding(SupportsShouldProcess)] param( [parameter(Mandatory = $true, ValueFromPipelinebyPropertyName = $true)] [Alias('id')] [String]$issuerName, #For AWS and GCP issuers only: keep the secrets (variables) associated with the issuer rather #than deleting them along with it. [parameter(Mandatory = $false, ValueFromPipelinebyPropertyName = $true)] [switch]$keep_secrets ) begin { }#begin process { $URI = "$($ISPSSSession.tenant_url)/api/issuers/$([uri]::EscapeDataString($issuerName))" if ($keep_secrets.IsPresent) { $URI = Add-QueryString -URI $URI -Parameter @{ keep_secrets = $true } } if ($PSCmdlet.ShouldProcess($issuerName, 'Delete Secrets Manager issuer')) { Invoke-IDRestMethod -Uri $URI -Method DELETE -Accept $(Get-SMApiHeader -Version V2) } }#process end { }#end } # .ExternalHelp IdentityCommand.SecretsManager-help.xml function Remove-SMNodeGroup { [CmdletBinding(SupportsShouldProcess)] param( [parameter(Mandatory = $true, ValueFromPipelinebyPropertyName = $true)] [Alias('name')] [String]$trustDomainName, [parameter(Mandatory = $true, ValueFromPipelinebyPropertyName = $true)] [String]$serverGroupName, [parameter(Mandatory = $true, ValueFromPipelinebyPropertyName = $true)] [String]$nodeGroupName ) begin { }#begin process { $URI = "$($ISPSSSession.tenant_url)/api/swa/trust-domains/$([uri]::EscapeDataString($trustDomainName))/server-groups/$([uri]::EscapeDataString($serverGroupName))/node-groups/$([uri]::EscapeDataString($nodeGroupName))" if ($PSCmdlet.ShouldProcess($nodeGroupName, 'Delete SWA node group')) { Invoke-IDRestMethod -Uri $URI -Method DELETE -Accept $(Get-SMApiHeader -Version V2) } }#process end { }#end } # .ExternalHelp IdentityCommand.SecretsManager-help.xml function Remove-SMServer { [CmdletBinding(SupportsShouldProcess)] param( [parameter(Mandatory = $true, ValueFromPipelinebyPropertyName = $true)] [Alias('name')] [String]$trustDomainName, [parameter(Mandatory = $true, ValueFromPipelinebyPropertyName = $true)] [String]$serverGroupName, [parameter(Mandatory = $true, ValueFromPipelinebyPropertyName = $true)] [String]$serverName ) begin { }#begin process { $URI = "$($ISPSSSession.tenant_url)/api/swa/trust-domains/$([uri]::EscapeDataString($trustDomainName))/server-groups/$([uri]::EscapeDataString($serverGroupName))/components/$([uri]::EscapeDataString($serverName))" if ($PSCmdlet.ShouldProcess($serverName, 'Delete SWA server')) { Invoke-IDRestMethod -Uri $URI -Method DELETE -Accept $(Get-SMApiHeader -Version V2) } }#process end { }#end } # .ExternalHelp IdentityCommand.SecretsManager-help.xml function Remove-SMServerGroup { [CmdletBinding(SupportsShouldProcess)] param( [parameter(Mandatory = $true, ValueFromPipelinebyPropertyName = $true)] [Alias('name')] [String]$trustDomainName, [parameter(Mandatory = $true, ValueFromPipelinebyPropertyName = $true)] [String]$serverGroupName ) begin { }#begin process { $URI = "$($ISPSSSession.tenant_url)/api/swa/trust-domains/$([uri]::EscapeDataString($trustDomainName))/server-groups/$([uri]::EscapeDataString($serverGroupName))" #Deletes every server in the group and their related Secrets Manager resources along with it. if ($PSCmdlet.ShouldProcess($serverGroupName, 'Delete SWA server group')) { Invoke-IDRestMethod -Uri $URI -Method DELETE -Accept $(Get-SMApiHeader -Version V2) } }#process end { }#end } # .ExternalHelp IdentityCommand.SecretsManager-help.xml function Remove-SMTrustDomain { [CmdletBinding(SupportsShouldProcess)] param( [parameter(Mandatory = $true, ValueFromPipelinebyPropertyName = $true)] [Alias('name')] [String]$trustDomainName ) begin { }#begin process { $URI = "$($ISPSSSession.tenant_url)/api/swa/trust-domains/$([uri]::EscapeDataString($trustDomainName))" #Deletes every resource inside the trust domain along with it. if ($PSCmdlet.ShouldProcess($trustDomainName, 'Delete SWA trust domain')) { Invoke-IDRestMethod -Uri $URI -Method DELETE -Accept $(Get-SMApiHeader -Version V2) } }#process end { }#end } # .ExternalHelp IdentityCommand.SecretsManager-help.xml function Remove-SMWorkload { [CmdletBinding(SupportsShouldProcess)] param( [parameter(Mandatory = $true, ValueFromPipelinebyPropertyName = $true)] [ValidateLength(3, 500)] [String]$identifier ) begin { }#begin process { $URI = "$($ISPSSSession.tenant_url)/api/workloads/$([uri]::EscapeDataString($identifier))" if ($PSCmdlet.ShouldProcess($identifier, 'Delete workload')) { #Send Request Invoke-IDRestMethod -Uri $URI -Method DELETE -Accept $(Get-SMApiHeader -Version Beta) } }#process end { }#end } # .ExternalHelp IdentityCommand.SecretsManager-help.xml function Remove-SMWorkloadAnnotation { [CmdletBinding(SupportsShouldProcess)] param( [parameter(Mandatory = $true, ValueFromPipelinebyPropertyName = $true)] [ValidateLength(3, 500)] [String]$identifier, [parameter(Mandatory = $true, ValueFromPipelinebyPropertyName = $true)] [ValidateLength(1, 1000)] [String]$annotationName ) begin { }#begin process { $URI = "$($ISPSSSession.tenant_url)/api/workloads/$([uri]::EscapeDataString($identifier))/annotations/$([uri]::EscapeDataString($annotationName))" if ($PSCmdlet.ShouldProcess($identifier, "Remove annotation '$annotationName'")) { #Send Request Invoke-IDRestMethod -Uri $URI -Method DELETE -Accept $(Get-SMApiHeader -Version Beta) } }#process end { }#end } # .ExternalHelp IdentityCommand.SecretsManager-help.xml function Set-SMAuthenticatorState { [CmdletBinding(SupportsShouldProcess)] param( [parameter(Mandatory = $true, ValueFromPipelinebyPropertyName = $true)] [ValidateSet('jwt', 'gcp', 'azure', 'aws_iam')] [String]$type, [parameter(Mandatory = $true, ValueFromPipelinebyPropertyName = $true)] [ValidateLength(1, 60)] [String]$name, #Only the enabled field is currently updatable on an authenticator. [parameter(Mandatory = $true, ValueFromPipelinebyPropertyName = $true)] [bool]$enabled ) begin { }#begin process { $URI = "$($ISPSSSession.tenant_url)/api/authenticators/$type/$([uri]::EscapeDataString($name))" $body = @{ enabled = $enabled } if ($PSCmdlet.ShouldProcess($name, "Set authenticator state: $(if ($enabled) { 'enable' } else { 'disable' })")) { $result = Invoke-IDRestMethod -Uri $URI -Method PATCH -Body ($body | ConvertTo-Json -Depth 2) -Accept $(Get-SMApiHeader -Version Beta) if ($null -ne $result) { $result } } }#process end { }#end } # .ExternalHelp IdentityCommand.SecretsManager-help.xml function Set-SMIssuer { [CmdletBinding(SupportsShouldProcess, DefaultParameterSetName = 'AWS')] param( [parameter(Mandatory = $true, ValueFromPipelinebyPropertyName = $true)] [Alias('id')] [String]$issuerName, [parameter(Mandatory = $false, ValueFromPipelinebyPropertyName = $true)] [ValidateRange(900, 43200)] [int]$max_ttl, #--- AWS --- [parameter(Mandatory = $true, ParameterSetName = 'AWS')] [ValidateLength(16, 16)] [String]$access_key_id, [parameter(Mandatory = $true, ParameterSetName = 'AWS')] [SecureString]$secret_access_key, #--- GCP --- [parameter(Mandatory = $true, ParameterSetName = 'GCP')] [ValidateLength(6, 500)] [String]$service_account_key_secret_ref, [parameter(Mandatory = $false, ParameterSetName = 'GCP')] [String[]]$access_token_permitted_scope ) begin { }#begin process { #Only AWS and GCP issuers can be updated - Certificate Manager (PKI_VENAFI_SAAS) issuers are #not, matching the spec's own note on this endpoint. $URI = "$($ISPSSSession.tenant_url)/api/issuers/$([uri]::EscapeDataString($issuerName))" $body = [ordered]@{} if ($PSBoundParameters.ContainsKey('max_ttl')) { $body['max_ttl'] = $max_ttl } if ($PSCmdlet.ParameterSetName -eq 'AWS') { $body['data'] = [ordered]@{ access_key_id = $access_key_id secret_access_key = $(ConvertTo-InsecureString -SecureString $secret_access_key) } } elseif ($PSCmdlet.ParameterSetName -eq 'GCP') { $GcpData = [ordered]@{ service_account_key_secret_ref = [ordered]@{ id = $service_account_key_secret_ref } } if ($PSBoundParameters.ContainsKey('access_token_permitted_scope')) { $GcpData['access_token_permitted_scope'] = @($access_token_permitted_scope) } $body['data'] = $GcpData } if ($PSCmdlet.ShouldProcess($issuerName, 'Update Secrets Manager issuer')) { $result = Invoke-IDRestMethod -Uri $URI -Method PATCH -Body ($body | ConvertTo-SecretBody -Depth 6) -Accept $(Get-SMApiHeader -Version V2) if ($null -ne $result) { $result } } }#process end { }#end } # .ExternalHelp IdentityCommand.SecretsManager-help.xml function Set-SMNodeGroup { [CmdletBinding(SupportsShouldProcess)] param( [parameter(Mandatory = $true, ValueFromPipelinebyPropertyName = $true)] [Alias('name')] [String]$trustDomainName, [parameter(Mandatory = $true, ValueFromPipelinebyPropertyName = $true)] [String]$serverGroupName, [parameter(Mandatory = $true, ValueFromPipelinebyPropertyName = $true)] [String]$nodeGroupName, #The name, workload_type and parent server group cannot be changed after creation. [parameter(Mandatory = $false, ValueFromPipelinebyPropertyName = $true)] [String]$description, [parameter(Mandatory = $false, ValueFromPipelinebyPropertyName = $true)] [String]$spiffe_id_template, [parameter(Mandatory = $false, ValueFromPipelinebyPropertyName = $true)] [String[]]$workload_registration_policies ) begin { }#begin process { $URI = "$($ISPSSSession.tenant_url)/api/swa/trust-domains/$([uri]::EscapeDataString($trustDomainName))/server-groups/$([uri]::EscapeDataString($serverGroupName))/node-groups/$([uri]::EscapeDataString($nodeGroupName))" $body = [ordered]@{} if ($PSBoundParameters.ContainsKey('description')) { $body['description'] = $description } $WorkloadConfig = [ordered]@{} if ($PSBoundParameters.ContainsKey('spiffe_id_template')) { $WorkloadConfig['spiffe_id_template'] = $spiffe_id_template } if ($PSBoundParameters.ContainsKey('workload_registration_policies')) { $WorkloadConfig['workload_registration_policies'] = @($workload_registration_policies) } if ($WorkloadConfig.Keys.Count -gt 0) { $body['workload_configuration'] = $WorkloadConfig } if ($PSCmdlet.ShouldProcess($nodeGroupName, 'Update SWA node group')) { $result = Invoke-IDRestMethod -Uri $URI -Method PATCH -Body ($body | ConvertTo-Json -Depth 5) -Accept $(Get-SMApiHeader -Version V2) if ($null -ne $result) { $result } } }#process end { }#end } # .ExternalHelp IdentityCommand.SecretsManager-help.xml function Set-SMServer { [CmdletBinding(SupportsShouldProcess)] param( [parameter(Mandatory = $true, ValueFromPipelinebyPropertyName = $true)] [Alias('name')] [String]$trustDomainName, [parameter(Mandatory = $true, ValueFromPipelinebyPropertyName = $true)] [String]$serverGroupName, [parameter(Mandatory = $true, ValueFromPipelinebyPropertyName = $true)] [String]$serverName, [parameter(Mandatory = $false, ValueFromPipelinebyPropertyName = $true)] [String]$ca_cert, [parameter(Mandatory = $false, ValueFromPipelinebyPropertyName = $true)] [String]$audience, [parameter(Mandatory = $false, ValueFromPipelinebyPropertyName = $true)] [String]$jwks_uri, [parameter(Mandatory = $false, ValueFromPipelinebyPropertyName = $true)] [hashtable]$public_keys, [parameter(Mandatory = $false, ValueFromPipelinebyPropertyName = $true)] [String]$issuer, [parameter(Mandatory = $false, ValueFromPipelinebyPropertyName = $true)] [hashtable]$claim_aliases, [parameter(Mandatory = $false, ValueFromPipelinebyPropertyName = $true)] [String[]]$enforced_claims, [parameter(Mandatory = $false, ValueFromPipelinebyPropertyName = $true)] [String]$identity_path, [parameter(Mandatory = $false, ValueFromPipelinebyPropertyName = $true)] [String]$token_app_property, [parameter(Mandatory = $false, ValueFromPipelinebyPropertyName = $true)] [hashtable]$annotations ) begin { }#begin process { #The sub claim and authentication type are not updatable, matching the spec's own note. $URI = "$($ISPSSSession.tenant_url)/api/swa/trust-domains/$([uri]::EscapeDataString($trustDomainName))/server-groups/$([uri]::EscapeDataString($serverGroupName))/components/$([uri]::EscapeDataString($serverName))" $Data = [ordered]@{} foreach ($p in 'ca_cert', 'audience', 'jwks_uri', 'public_keys', 'issuer') { if ($PSBoundParameters.ContainsKey($p)) { $Data[$p] = $PSBoundParameters[$p] } } $Identity = [ordered]@{} foreach ($p in 'claim_aliases', 'enforced_claims', 'identity_path', 'token_app_property') { if ($PSBoundParameters.ContainsKey($p)) { $Identity[$p] = $PSBoundParameters[$p] } } if ($Identity.Keys.Count -gt 0) { $Data['identity'] = $Identity } $Authentication = [ordered]@{} if ($Data.Keys.Count -gt 0) { $Authentication['data'] = $Data } if ($PSBoundParameters.ContainsKey('annotations')) { $Authentication['annotations'] = $annotations } if ($Authentication.Keys.Count -eq 0) { throw 'Supply at least one setting to update' } $body = [ordered]@{ authentication = $Authentication } if ($PSCmdlet.ShouldProcess($serverName, 'Update SWA server')) { $result = Invoke-IDRestMethod -Uri $URI -Method PATCH -Body ($body | ConvertTo-Json -Depth 6) -Accept $(Get-SMApiHeader -Version V2) if ($null -ne $result) { $result } } }#process end { }#end } # .ExternalHelp IdentityCommand.SecretsManager-help.xml function Set-SMServerGroup { [CmdletBinding(SupportsShouldProcess)] param( [parameter(Mandatory = $true, ValueFromPipelinebyPropertyName = $true)] [Alias('name')] [String]$trustDomainName, [parameter(Mandatory = $true, ValueFromPipelinebyPropertyName = $true)] [String]$serverGroupName, [parameter(Mandatory = $false, ValueFromPipelinebyPropertyName = $true)] [ValidateLength(0, 1024)] [String]$description, [parameter(Mandatory = $false, ValueFromPipelinebyPropertyName = $true)] [String[]]$gcp_service_account_allowed_project_ids, [parameter(Mandatory = $false, ValueFromPipelinebyPropertyName = $true)] [String[]]$gcp_service_account_audiences, [parameter(Mandatory = $false, ValueFromPipelinebyPropertyName = $true)] [String]$aws_iid_assume_role, [parameter(Mandatory = $false, ValueFromPipelinebyPropertyName = $true)] [ValidateSet('aws', 'aws-cn', 'aws-us-gov')] [String]$aws_iid_partition, [parameter(Mandatory = $false, ValueFromPipelinebyPropertyName = $true)] [String]$aws_iid_management_account_id, [parameter(Mandatory = $false, ValueFromPipelinebyPropertyName = $true)] [String]$aws_iid_management_account_region, [parameter(Mandatory = $false, ValueFromPipelinebyPropertyName = $true)] [String]$aws_iid_assume_org_role, [parameter(Mandatory = $false, ValueFromPipelinebyPropertyName = $true)] [String]$aws_iid_org_account_map_ttl, [parameter(Mandatory = $false, ValueFromPipelinebyPropertyName = $true)] [String]$aws_iid_account_list_file ) begin { }#begin process { $URI = "$($ISPSSSession.tenant_url)/api/swa/trust-domains/$([uri]::EscapeDataString($trustDomainName))/server-groups/$([uri]::EscapeDataString($serverGroupName))" $body = [ordered]@{} if ($PSBoundParameters.ContainsKey('description')) { $body['description'] = $description } $Attestation = [ordered]@{} if ($PSBoundParameters.ContainsKey('gcp_service_account_allowed_project_ids')) { $Gcp = [ordered]@{ allowed_project_ids = @($gcp_service_account_allowed_project_ids) } if ($PSBoundParameters.ContainsKey('gcp_service_account_audiences')) { $Gcp['audiences'] = @($gcp_service_account_audiences) } $Attestation['gcp_service_account'] = $Gcp } $AwsIidParams = 'aws_iid_assume_role', 'aws_iid_partition' if (($AwsIidParams | Where-Object { $PSBoundParameters.ContainsKey($_) }) -or ($PSBoundParameters.ContainsKey('aws_iid_management_account_id'))) { $AwsIid = [ordered]@{} if ($PSBoundParameters.ContainsKey('aws_iid_assume_role')) { $AwsIid['assume_role'] = $aws_iid_assume_role } if ($PSBoundParameters.ContainsKey('aws_iid_partition')) { $AwsIid['partition'] = $aws_iid_partition } $VerifyOrg = [ordered]@{} foreach ($p in 'management_account_id', 'management_account_region', 'assume_org_role', 'org_account_map_ttl', 'account_list_file') { $ParamName = "aws_iid_$p" if ($PSBoundParameters.ContainsKey($ParamName)) { $VerifyOrg[$p] = $PSBoundParameters[$ParamName] } } if ($VerifyOrg.Keys.Count -gt 0) { $AwsIid['verify_organization'] = $VerifyOrg } $Attestation['aws_iid'] = $AwsIid } if ($Attestation.Keys.Count -gt 0) { $body['attestation'] = $Attestation } if ($PSCmdlet.ShouldProcess($serverGroupName, 'Update SWA server group')) { $result = Invoke-IDRestMethod -Uri $URI -Method PATCH -Body ($body | ConvertTo-Json -Depth 6) -Accept $(Get-SMApiHeader -Version V2) if ($null -ne $result) { $result } } }#process end { }#end } # .ExternalHelp IdentityCommand.SecretsManager-help.xml function Set-SMTrustDomain { [CmdletBinding(SupportsShouldProcess)] param( [parameter(Mandatory = $true, ValueFromPipelinebyPropertyName = $true)] [Alias('name')] [String]$trustDomainName, [parameter(Mandatory = $false, ValueFromPipelinebyPropertyName = $true)] [ValidateSet('EC_P256', 'EC_P384', 'EC_P521', 'RSA_2048', 'RSA_4096')] [String]$signing_key_type, [parameter(Mandatory = $false, ValueFromPipelinebyPropertyName = $true)] [ValidateSet('ES256', 'ES384', 'ES512', 'RS256', 'RS384', 'RS512')] [String]$signature_algorithm, #NOTE: the update range (3600-86400) is narrower than create's (3600-2592000) - a signing key #can only be extended up to 24 hours through this call. [parameter(Mandatory = $false, ValueFromPipelinebyPropertyName = $true)] [ValidateRange(3600, 86400)] [int]$signing_key_ttl, [parameter(Mandatory = $false, ValueFromPipelinebyPropertyName = $true)] [ValidateRange(60, 86400)] [int]$token_ttl, [parameter(Mandatory = $false, ValueFromPipelinebyPropertyName = $true)] [ValidateRange(600, 86400)] [int]$workload_ttl ) begin { }#begin process { $URI = "$($ISPSSSession.tenant_url)/api/swa/trust-domains/$([uri]::EscapeDataString($trustDomainName))" $body = [ordered]@{} $Jwt = [ordered]@{} foreach ($p in 'signing_key_type', 'signature_algorithm', 'signing_key_ttl', 'token_ttl') { if ($PSBoundParameters.ContainsKey($p)) { $Jwt[$p] = $PSBoundParameters[$p] } } if ($Jwt.Keys.Count -gt 0) { $body['jwt'] = $Jwt } #x509's workload_ttl is required if x509 is sent at all - update requests it directly. if ($PSBoundParameters.ContainsKey('workload_ttl')) { $body['x509'] = [ordered]@{ workload_ttl = $workload_ttl } } if ($body.Keys.Count -eq 0) { throw 'Supply at least one setting to update' } if ($PSCmdlet.ShouldProcess($trustDomainName, 'Update SWA trust domain')) { $result = Invoke-IDRestMethod -Uri $URI -Method PATCH -Body ($body | ConvertTo-Json -Depth 4) -Accept $(Get-SMApiHeader -Version V2) if ($null -ne $result) { $result } } }#process end { }#end } #Copy IdentityCommand's private helpers into this module: this module's functions call them, and #the argument completer registrations below do so at import time. #Each copy is created from the function definition, so it runs in this module's scope and uses this #module's $ISPSSSession, whether IdentityCommand loaded from source or from its combined psm1. #Resolve a single IdentityCommand module: with more than one version loaded, Get-Module returns #an array. $Module = Get-Module -Name IdentityCommand | Sort-Object Version -Descending | Select-Object -First 1 if ($null -eq $Module) { throw 'The IdentityCommand module is not loaded. Import IdentityCommand and try again.' } & $Module { Get-ChildItem -Path Function: } | Where-Object { $_.ModuleName -eq $Module.Name -and -not $Module.ExportedFunctions.ContainsKey($_.Name) } | ForEach-Object { . ([scriptblock]::Create("function $($_.Name) {$($_.Definition)}")) } #region Registration Register-ArgumentCompleter -ParameterName 'trustDomainName' -ScriptBlock ( Get-ArgumentCompleter -RetrievalCommand 'Get-SMTrustDomain' -ValueProperty 'name' -LabelProperty 'name' ) -CommandName 'Get-SMTrustDomain', 'Set-SMTrustDomain', 'Remove-SMTrustDomain', 'Get-SMCABundle', 'Get-SMServerGroup', 'New-SMServerGroup', 'Set-SMServerGroup', 'Remove-SMServerGroup', 'Get-SMNodeGroup', 'New-SMNodeGroup', 'Set-SMNodeGroup', 'Remove-SMNodeGroup', 'Get-SMServer', 'New-SMServer', 'Set-SMServer', 'Remove-SMServer', 'Get-SMOpenIDConfiguration', 'Get-SMJwks' Register-ArgumentCompleter -ParameterName 'issuerName' -ScriptBlock ( Get-ArgumentCompleter -RetrievalCommand 'Get-SMIssuer' -ValueProperty 'id' -LabelProperty 'id' ) -CommandName 'Set-SMIssuer', 'Remove-SMIssuer', 'New-SMIssuedCertificate', 'New-SMSignedCertificate' #endregion Registration # Script scope session object for session data $ISPSSSession = [ordered]@{ tenant_url = $null User = $null TenantId = $null SessionId = $null WebSession = $null StartTime = $null ElapsedTime = $null LastCommand = $null LastCommandTime = $null LastCommandResults = $null LastError = $null LastErrorTime = $null } | Add-CustomType -Type IdCmd.Session New-Variable -Name ISPSSSession -Value $ISPSSSession -Scope Script -Force |