Skip to content

Implement Context integration for storing API keys #21

@MariusStorhaug

Description

@MariusStorhaug

Summary

Implement the Context module integration for PowerShellGallery to securely store and manage API keys for the PowerShell Gallery.

Background

The Context module (PSModule/Context) provides a secure, encrypted storage mechanism for module settings and user credentials. The GitHub module (PSModule/GitHub) serves as a reference implementation showing how to integrate Context.

Requirements

1. Connect-PowerShellGallery Function

Create a function that enables users to connect to the PowerShell Gallery by storing an API key context.

Behavior:

  • When called, it should open the user's browser to the PowerShell Gallery API key management page: https://www.powershellgallery.com/account/apikeys
  • Prompt the user to enter their API key (as SecureString)
  • Store the context using the Context module with the vault name PSModule.PowerShellGallery
  • Support storing multiple contexts (e.g., for different accounts/organizations)
  • Return the created context object when -PassThru is specified

Parameters:

  • -Name - A friendly name/identifier for this connection context
  • -ApiKey - (Optional) The API key as a SecureString. If not provided, prompt the user
  • -PassThru - Return the context object after creation
  • -Silent - Suppress informational output

Example:

# Interactive flow - opens browser and prompts for API key
Connect-PowerShellGallery -Name 'MyAccount'

# Programmatic flow - provide API key directly
Connect-PowerShellGallery -Name 'CIAccount' -ApiKey $secureApiKey

2. Test-PowerShellGalleryAccess Function

Create a function that validates the stored API key by testing access to the PowerShell Gallery API.

Behavior:

  • Use the stored context to authenticate
  • Query the PowerShell Gallery API to retrieve packages published by the account
  • Return information about the account's published packages

Parameters:

  • -Context - (Optional) The context to use. If not specified, use the default context

Example:

# Test access using the default context
Test-PowerShellGalleryAccess

# Test access using a specific context
Test-PowerShellGalleryAccess -Context 'MyAccount'

3. Supporting Functions

Implement supporting functions following the pattern from the GitHub module:

  • Get-PowerShellGalleryContext - Retrieve stored contexts
  • Switch-PowerShellGalleryContext - Set the default context
  • Disconnect-PowerShellGallery - Remove a stored context
  • Get-PowerShellGalleryAccessToken - Retrieve the API key (as SecureString or plain text with -AsPlainText)

Implementation Details

Context Storage Pattern

Reference the GitHub module's implementation:

# Module-level variable for vault configuration
$script:PowerShellGallery = @{
    ContextVault = 'PSModule.PowerShellGallery'
    DefaultConfig = @{
        ID = 'Module'
        DefaultContext = $null
        GalleryUrl = 'https://www.powershellgallery.com'
        ApiUrl = 'https://www.powershellgallery.com/api/v2'
    }
}

Context Object Structure

@{
    ID = 'MyAccount'  # Unique identifier
    Name = 'MyAccount'  # Display name
    ApiKey = <SecureString>  # The API key (encrypted by Context module)
    GalleryUrl = 'https://www.powershellgallery.com'
    ConnectedAt = <DateTime>
}

Wrapper Functions Pattern

From the Context module's best practices:

function Set-PowerShellGalleryContext {
    param(
        [Parameter(Mandatory)]
        [string] $ID,
        
        [Parameter(Mandatory)]
        [object] $Context
    )
    
    Set-Context -ID $ID -Vault $script:PowerShellGallery.ContextVault -Context $Context
}

function Get-PowerShellGalleryContext {
    param(
        [string] $ID = '*'
    )
    
    Get-Context -ID $ID -Vault $script:PowerShellGallery.ContextVault
}

Dependencies

  • Context module (for secure storage)
  • PowerShell Gallery NuGet API v2/v3

References

Testing

Build out tests using the APIKEY secret available in the workflow. We need the function be able to work in a non-interactive way to make sure this works.

Metadata

Metadata

Labels

enhancementNew feature or request

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions