PPDS.Auth 1.0.0-beta.6

This is a prerelease version of PPDS.Auth.
dotnet add package PPDS.Auth --version 1.0.0-beta.6
                    
NuGet\Install-Package PPDS.Auth -Version 1.0.0-beta.6
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="PPDS.Auth" Version="1.0.0-beta.6" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="PPDS.Auth" Version="1.0.0-beta.6" />
                    
Directory.Packages.props
<PackageReference Include="PPDS.Auth" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add PPDS.Auth --version 1.0.0-beta.6
                    
#r "nuget: PPDS.Auth, 1.0.0-beta.6"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package PPDS.Auth@1.0.0-beta.6
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=PPDS.Auth&version=1.0.0-beta.6&prerelease
                    
Install as a Cake Addin
#tool nuget:?package=PPDS.Auth&version=1.0.0-beta.6&prerelease
                    
Install as a Cake Tool

PPDS.Auth

Authentication profile management for Power Platform with encrypted credential storage and multi-cloud support.

Installation

dotnet add package PPDS.Auth

Quick Start

// 1. Create and store a profile
var store = new ProfileStore();
var profile = new AuthProfile("dev")
{
    AuthMethod = AuthMethod.InteractiveBrowser,
    ClientId = "51f81489-12ee-4a9e-aaae-a2591f45987d" // Default Power Platform client
};
await store.SaveAsync(profile);

// 2. Authenticate and get a ServiceClient
var provider = CredentialProviderFactory.Create(profile);
var client = await ServiceClientFactory.CreateAsync(provider, profile);

Features

Profile Storage

Profiles are stored with encrypted secrets (DPAPI on Windows):

var store = new ProfileStore();

// Save a profile
await store.SaveAsync(profile);

// Load all profiles
var profiles = await store.LoadAsync();

// Get active profile
var active = profiles.GetActiveProfile();

// Set active profile
profiles.SetActive("dev");
await store.SaveAsync(profiles);

Default storage location: ~/.ppds/profiles.json

Authentication Methods

// Interactive Browser (opens browser for OAuth)
var profile = new AuthProfile("dev")
{
    AuthMethod = AuthMethod.InteractiveBrowser,
    ClientId = "51f81489-12ee-4a9e-aaae-a2591f45987d"
};

// Device Code (for headless/SSH environments)
var profile = new AuthProfile("dev")
{
    AuthMethod = AuthMethod.DeviceCode,
    ClientId = "51f81489-12ee-4a9e-aaae-a2591f45987d"
};

// Client Secret (service principal)
var profile = new AuthProfile("ci")
{
    AuthMethod = AuthMethod.ClientSecret,
    ApplicationId = "your-app-id",
    TenantId = "your-tenant-id",
    ClientSecret = "your-secret"  // Stored encrypted
};

// Certificate File
var profile = new AuthProfile("prod")
{
    AuthMethod = AuthMethod.CertificateFile,
    ApplicationId = "your-app-id",
    TenantId = "your-tenant-id",
    CertificatePath = "/path/to/cert.pfx",
    CertificatePassword = "password"  // Stored encrypted
};

// Certificate Store (Windows)
var profile = new AuthProfile("prod")
{
    AuthMethod = AuthMethod.CertificateStore,
    ApplicationId = "your-app-id",
    TenantId = "your-tenant-id",
    CertificateThumbprint = "ABC123...",
    CertificateStoreLocation = StoreLocation.CurrentUser
};

// Managed Identity (Azure-hosted)
var profile = new AuthProfile("azure")
{
    AuthMethod = AuthMethod.ManagedIdentity,
    ManagedIdentityClientId = "user-assigned-id"  // Optional for user-assigned
};

// GitHub Actions OIDC
var profile = new AuthProfile("github")
{
    AuthMethod = AuthMethod.GitHubFederated,
    ApplicationId = "your-app-id",
    TenantId = "your-tenant-id"
};

// Azure DevOps OIDC
var profile = new AuthProfile("azdo")
{
    AuthMethod = AuthMethod.AzureDevOpsFederated,
    ApplicationId = "your-app-id",
    TenantId = "your-tenant-id",
    AzureDevOpsServiceConnectionId = "service-connection-id"
};

Environment Discovery

Discover environments accessible to the authenticated user:

var provider = CredentialProviderFactory.Create(profile);
var discovery = new GlobalDiscoveryService();

var environments = await discovery.GetEnvironmentsAsync(provider.GetTokenAsync);

foreach (var env in environments)
{
    Console.WriteLine($"{env.FriendlyName} - {env.Url}");
}

Environment Resolution

Resolve environments by various identifiers:

var resolver = new EnvironmentResolver(discovery, provider.GetTokenAsync);

// By URL
var env = await resolver.ResolveAsync("https://org.crm.dynamics.com");

// By unique name
var env = await resolver.ResolveAsync("org");

// By environment ID
var env = await resolver.ResolveAsync("00000000-0000-0000-0000-000000000000");

// By partial friendly name (fuzzy match)
var env = await resolver.ResolveAsync("Production");

Multi-Cloud Support

var profile = new AuthProfile("gcc")
{
    Cloud = CloudEnvironment.UsGov,  // GCC
    // ... other settings
};

// Supported clouds:
// - CloudEnvironment.Public (default)
// - CloudEnvironment.UsGov (GCC)
// - CloudEnvironment.UsGovHigh (GCC High)
// - CloudEnvironment.UsGovDoD (DoD)
// - CloudEnvironment.China
// - CloudEnvironment.UsNat
// - CloudEnvironment.UsSec

Integration with PPDS.Dataverse

Use profiles as a connection source for the connection pool:

var store = new ProfileStore();
var profiles = await store.LoadAsync();
var profile = profiles.GetActiveProfile();

var provider = CredentialProviderFactory.Create(profile);
var source = new ProfileConnectionSource(profile, provider);

services.AddDataverseConnectionPool(options =>
{
    options.ConnectionSources.Add(source);
});

Custom Credential Providers

Implement ICredentialProvider for custom authentication:

public class CustomCredentialProvider : ICredentialProvider
{
    public string Name => "Custom";
    public bool RequiresInteraction => false;

    public Task<string> GetTokenAsync(string resource, CancellationToken ct)
    {
        // Your custom token acquisition logic
        return Task.FromResult("your-token");
    }

    public Task<TokenInfo> GetTokenInfoAsync(CancellationToken ct)
    {
        return Task.FromResult(new TokenInfo
        {
            UserPrincipalName = "user@example.com",
            TenantId = "..."
        });
    }
}

Security

Credential Encryption

Secrets (client secrets, passwords, etc.) are encrypted at rest:

  • Windows: DPAPI (user-scoped encryption)
  • Linux/macOS: Base64 encoding (use OS-level file permissions)

Token Caching

MSAL token caching is used for interactive and device code flows:

var profile = new AuthProfile("dev")
{
    TokenCacheType = TokenCacheType.Persistent  // Default
    // TokenCacheType = TokenCacheType.InMemory  // Per-process only
};

Target Frameworks

  • net8.0
  • net9.0
  • net10.0

License

MIT License

Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 is compatible.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.0.0-beta.6 41 1/17/2026
1.0.0-beta.5 45 1/6/2026
1.0.0-beta.4 45 1/3/2026
1.0.0-beta.3 50 1/2/2026
1.0.0-beta.2 43 1/1/2026
1.0.0-beta.1 49 12/29/2025