Skip to content

Integrate 1Password secrets into .NET applications during development using the op CLI. Automatically resolves op:// references in IConfiguration.

License

Notifications You must be signed in to change notification settings

ArkanisCorporation/Hosting.Extensions.1Password

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

26 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

πŸ” Arkanis.Hosting.Extensions.1Password

Seamlessly integrate 1Password secrets into your .NET applications during development.

NuGet Aspire NuGet License


✨ Why This Library?

If you love 1Password (and who doesn't?) and want to bring that same level of security and convenience to your .NET development workflow, this library is for you.

The Problem: Managing secrets during development is painful. You don't want to commit API keys, connection strings, or passwords to source control, but you also don't want to juggle multiple files, environment variables, or complicated secret management systems just to run your app locally.

The Solution: This library bridges the gap between 1Password and your .NET application's configuration system. Just reference your 1Password secrets using the op:// URI scheme in your existing configuration files, and let the library handle the rest. No changes to your existing configuration infrastructure required!

πŸš€ Features

  • 🎯 Zero Configuration Changes Required - Works seamlessly with your existing IConfiguration setup
  • πŸ”„ Universal Compatibility - Supports appsettings.json, environment variables, or any configuration source
  • ⚑ Async-First Design - Built for modern .NET with full async/await support
  • πŸ§ͺ Fully Testable - Comes with a mockable interface for unit testing
  • 🌐 Multi-Account Support - Specify which 1Password account to use
  • 🎨 Developer-Friendly - Simple API with just one method call to set up
  • πŸ“¦ Lightweight - Built on .NET Standard 2.1 for broad compatibility
  • 🐳 Aspire Integration - First-class support for .NET Aspire distributed applications
  • πŸ”— Parameter Resources - Add individual 1Password secrets as Aspire parameter resources

πŸ“¦ Installation

Core Library

Install via NuGet Package Manager:

dotnet add package Arkanis.Hosting.Extensions.1Password

Or via Package Manager Console:

Install-Package Arkanis.Hosting.Extensions.1Password

Aspire Integration (Optional)

For use with .NET Aspire projects:

dotnet add package Arkanis.Aspire.Hosting.Extensions.1Password

Or via Package Manager Console:

Install-Package Arkanis.Aspire.Hosting.Extensions.1Password

🎯 Quick Start

1. Store your secrets in 1Password

Create a secret in 1Password (e.g., an API key in the "Private" vault under "MyApp/ApiKey").

2. Reference it in your configuration

Add a reference to your secret in appsettings.json using the op:// URI scheme:

{
  "ApiKey": "op://Private/MyApp/ApiKey",
  "Database": {
    "ConnectionString": "op://Private/MyApp/database-connection"
  }
}

3. Enable 1Password integration

Add one line to your application startup:

using Hosting.Extensions._1Password;

var builder = Host.CreateApplicationBuilder(args);

// That's it! πŸŽ‰
await builder.Use1PasswordAsync("my.1password.com");
// or builder.Use1Password("my.1password.com");

var host = builder.Build();
await host.RunAsync();

4. Access your secrets normally

Your secrets are now available through the standard IConfiguration interface. They are only resolved in-memory at runtime, so your configuration files remain clean.

var apiKey = builder.Configuration["ApiKey"];
var connectionString = builder.Configuration["Database:ConnectionString"];

// Use them as you normally would!

πŸ“š Usage Examples

Basic Usage

var builder = Host.CreateApplicationBuilder(args);

// Resolve secrets from your default 1Password account
await builder.Use1PasswordAsync();

var host = builder.Build();
await host.RunAsync();

Specify a 1Password Account

var builder = Host.CreateApplicationBuilder(args);

// Use a specific 1Password account or sign-in address
await builder.Use1PasswordAsync("my.1password.com");

var host = builder.Build();
await host.RunAsync();

Synchronous API

If you prefer synchronous code:

var builder = Host.CreateApplicationBuilder(args);

// Synchronous version (blocks until secrets are resolved)
builder.Use1Password("my.1password.com");

var host = builder.Build();
host.Run();

Use in ASP.NET Core

Works perfectly with ASP.NET Core applications:

var builder = WebApplication.CreateBuilder(args);

// Inject 1Password secrets before registering services
await builder.Use1PasswordAsync("my.1password.com");

builder.Services.AddControllers();
// ... register other services

var app = builder.Build();
app.Run();

Environment-Specific Configuration

Only use 1Password in development:

var builder = Host.CreateApplicationBuilder(args);

if (builder.Environment.IsDevelopment())
{
    await builder.Use1PasswordAsync("my.1password.com");
}

var host = builder.Build();
await host.RunAsync();

.NET Aspire Integration

Use 1Password with .NET Aspire for distributed application configuration:

Using Aspire with Automatic Secret Resolution

using Aspire.Hosting;
using Arkanis.Aspire.Hosting.Extensions._1Password;

var builder = DistributedApplication.CreateBuilder(args);

// Inject secrets into the AppHost configuration
await builder.Use1PasswordAsync("my.1password.com");
// or
await builder.Use1PasswordAsync(options =>
{
    options.Account = "my.1password.com";
    // Additional options can be configured here
});

// ...
builder.Build().Run();

Using Aspire Parameter Resources

Add individual 1Password parameters as Aspire resources:

using Aspire.Hosting;
using Arkanis.Aspire.Hosting.Extensions._1Password;

var builder = DistributedApplication.CreateBuilder(args);

// Add a specific 1Password secret as a parameter resource
builder.Add1PasswordParameter(
    key: "ApiKey",
    onePasswordKey: "op://Private/MyApp/ApiKey",
    account: "my.1password.com"
);

// ...
builder.Build().Run();

Complex Configuration Structures

The library automatically traverses nested configuration:

{
  "Authentication": {
    "Google": {
      "ClientId": "op://Private/OAuth/Google/client-id",
      "ClientSecret": "op://Private/OAuth/Google/client-secret"
    },
    "GitHub": {
      "ClientId": "op://Private/OAuth/GitHub/client-id",
      "ClientSecret": "op://Private/OAuth/GitHub/client-secret"
    }
  },
  "Database": {
    "Primary": "op://Private/Database/primary-connection",
    "Readonly": "op://Private/Database/readonly-connection"
  }
}

All op:// references are automatically detected and resolved, no matter how deeply nested!

πŸ§ͺ Testing

The library is designed with testability in mind. Use the IOpCliInvoker interface to mock 1Password CLI calls in your tests:

using NSubstitute;

// Create a mock invoker
var mockInvoker = Substitute.For<IOpCliInvoker>();
mockInvoker.InvokeAsync(Arg.Any<string?>(), Arg.Any<string>())
    .Returns(new BufferedCommandResult(
        exitCode: 0,
        standardOutput: "ApiKey=\"test-api-key-123\"",
        standardError: ""
    ));

// Use it in your tests
var builder = Host.CreateApplicationBuilder(args);
await builder.Use1PasswordAsync(
    account: "my.1password.com",
    opCliInvoker: mockInvoker
);

// Verify the configuration was populated
Assert.Equal("test-api-key-123", builder.Configuration["ApiKey"]);

πŸ“‹ Requirements

Core Library

  • .NET Runtime: .NET Standard 2.1 or higher (supports .NET Core 3.0+, .NET 5+, .NET 6+, etc.)
  • 1Password CLI: The op CLI must be installed and available in your PATH
  • Authentication: You must be signed in to 1Password (the CLI will use your existing session)

Aspire Package

  • .NET Runtime: .NET 8.0, 9.0, or 10.0
  • 1Password CLI: The op CLI must be installed and available in your PATH
  • Authentication: You must be signed in to 1Password (the CLI will use your existing session)

Installation

To install the 1Password CLI:

# macOS (via Homebrew)
brew install 1password-cli

# Windows (via WinGet)
winget install 1password-cli

# Or download from: https://developer.1password.com/docs/cli/get-started/

πŸ”§ How It Works

Core Library (Arkanis.Hosting.Extensions.1Password)

  1. Detection: The library scans your IConfiguration for any values starting with op://
  2. Templating: It builds a template with all detected secret references
  3. Resolution: It invokes the 1Password CLI (op inject) to resolve all secrets in one call
  4. Injection: The resolved values are written back into your configuration in-memory

All of this happens transparently during application startup, before your services are registered or initialized.

Aspire Integration (Arkanis.Aspire.Hosting.Extensions.1Password)

The Aspire package extends the core library with features tailored for distributed applications:

  • AppHost Integration: Resolve 1Password secrets in your AppHost project configuration
  • Parameter Resources: Add individual 1Password secrets as Aspire parameter resources that can be referenced by services
  • Dual APIs: Both async (Use1PasswordAsync) and sync (Use1Password) methods for compatibility with IHostApplicationBuilder

🎯 Use Cases

This library is perfect for:

  • βœ… Local development - Keep secrets secure while developing locally
  • βœ… Team collaboration - Share secret references (not secrets themselves) in source control
  • βœ… Rapid prototyping - Get started quickly without complex secret management
  • βœ… Multi-environment setups - Different secrets per environment, same configuration structure

Not recommended for:

  • ❌ Production deployments - Use your platform's native secret management (Azure Key Vault, AWS Secrets Manager, etc.)

🀝 Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

Building from Source

# Clone the repository
git clone https://github.com/ArkanisCorporation/Hosting.Extensions.1Password.git
cd Hosting.Extensions.1Password

# Restore dependencies
dotnet restore

# Build the solution
dotnet build

# Run tests
dotnet test

πŸ“„ License

This project is licensed under the MIT License - see the LICENSE.md file for details.

πŸ™ Acknowledgments

  • Built with ❀️ for the .NET and 1Password communities
  • Powered by CliWrap for reliable CLI invocation
  • Inspired by the amazing developer experience that 1Password provides

πŸ“ž Support


Made with πŸ” by developers who love 1Password

About

Integrate 1Password secrets into .NET applications during development using the op CLI. Automatically resolves op:// references in IConfiguration.

Topics

Resources

License

Code of conduct

Contributing

Stars

Watchers

Forks

Packages

No packages published