{"id":28287024,"url":"https://github.com/yellowlineparking/appy.configuration","last_synced_at":"2025-10-18T02:17:04.877Z","repository":{"id":46085283,"uuid":"300303448","full_name":"YellowLineParking/Appy.Configuration","owner":"YellowLineParking","description":"Appy Configuration Providers","archived":false,"fork":false,"pushed_at":"2024-11-18T10:00:29.000Z","size":436,"stargazers_count":4,"open_issues_count":0,"forks_count":0,"subscribers_count":5,"default_branch":"master","last_synced_at":"2025-05-21T22:11:33.278Z","etag":null,"topics":["1password","1password-cli","configuration","configuration-builder","docker","dotnet","netcore","vault","windows-registry"],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/YellowLineParking.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE.md","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2020-10-01T14:12:24.000Z","updated_at":"2024-11-18T10:00:33.000Z","dependencies_parsed_at":"2024-11-19T04:18:15.606Z","dependency_job_id":null,"html_url":"https://github.com/YellowLineParking/Appy.Configuration","commit_stats":null,"previous_names":[],"tags_count":15,"template":false,"template_full_name":null,"purl":"pkg:github/YellowLineParking/Appy.Configuration","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/YellowLineParking%2FAppy.Configuration","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/YellowLineParking%2FAppy.Configuration/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/YellowLineParking%2FAppy.Configuration/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/YellowLineParking%2FAppy.Configuration/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/YellowLineParking","download_url":"https://codeload.github.com/YellowLineParking/Appy.Configuration/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/YellowLineParking%2FAppy.Configuration/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":260488408,"owners_count":23016907,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["1password","1password-cli","configuration","configuration-builder","docker","dotnet","netcore","vault","windows-registry"],"created_at":"2025-05-21T22:10:59.337Z","updated_at":"2025-10-18T02:17:04.869Z","avatar_url":"https://github.com/YellowLineParking.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"# `Appy.Configuration`\r\n\r\n![AppyWay logo](resources/appyway-100x100.png)\r\n\r\n## What is Appy.Configuration?\r\n\r\nConfiguration providers for Dotnet.\r\n\r\nThe latest supported version of 1Password CLI is 2.23.0. In case you want to use 1Password CLI 1, install version 0.11.0 for any of the Appy packages.\r\n\r\n## Configuration Providers\r\n\r\n| Package | Latest Stable |\r\n| --- | --- |\r\n| [Appy.Configuration.1Password](https://www.nuget.org/packages/Appy.Configuration.1Password) | [![Nuget Package](https://img.shields.io/badge/nuget-1.2.0-blue.svg)](https://www.nuget.org/packages/Appy.Configuration.1Password) |\r\n| [appy-op](https://www.nuget.org/packages/appy-op) | [![Nuget Package](https://img.shields.io/badge/nuget-1.2.0-blue.svg)](https://www.nuget.org/packages/appy-op) \r\n| [appy-op (Docker Image)](https://hub.docker.com/r/appyway/appy-op/tags?page=1\u0026ordering=last_updated) | [![Docker Image](https://img.shields.io/badge/docker-1.2.0-blue.svg)](https://hub.docker.com/r/appyway/appy-op/tags?page=1\u0026ordering=last_updated) |\r\n| [Appy.Configuration.WinRegistry](https://www.nuget.org/packages/Appy.Configuration.WinRegistry) | [![Nuget Package](https://img.shields.io/badge/nuget-1.2.0-blue.svg)](https://www.nuget.org/packages/Appy.Configuration.WinRegistry) |\r\n\r\n## Table of Contents\r\n\r\n- [1Password Configuration Provider](#1password-configuration-provider)\r\n    * [Installing](#installing)\r\n    * [Usage](#usage)\r\n- [Appy 1Password Tool](#appy-1password-tool)\r\n    * [Prerequisites](#prerequisites)\r\n    * [Installing](#installing-1)\r\n    * [Signin to 1Password](#signin-to-1password)\r\n    * [Auto-renew session activity](#auto-renew-session-activity)\r\n    * [Nano Api and Docker](#nano-api-and-docker)\r\n    * [Tool as Docker Image](#tool-as-docker-image)\r\n- [Windows Registry Configuration Provider](#windows-registry-configuration-provider)\r\n    * [Installing](#installing-2)\r\n    * [Usage](#usage-1)\r\n\r\n## 1Password Configuration Provider\r\n\r\n1Password is one of those services that makes our life easier every day, storing all our passwords in a secure manner.\r\n\r\nWith this extension you can extend the power of 1Password and easily configure the loading of settings from 1Password to your NETCore project configuration builder.\r\n\r\n### Installing\r\n\r\nInstall using the [Appy.Configuration.1Password NuGet package](https://www.nuget.org/packages/Appy.Configuration.1Password):\r\n\r\n```\r\nPM\u003e Install-Package Appy.Configuration.1Password\r\n```\r\n\r\n### Usage\r\n\r\nWhen you install the package, it should be added to your _csproj_ file. Alternatively, you can add it directly by adding:\r\n\r\n```xml\r\n\u003cPackageReference Include=\"Appy.Configuration.1Password\" Version=\"1.2.0\" /\u003e\r\n```\r\n\r\nLet's imagine we have a configuration file like the following appsettings.json file:\r\n\r\n```json\r\n\"Database\": {\r\n    \"ConnectionString\": \"\"\r\n}\r\n```\r\n\r\nAnd your project settings on 1Password. You should create a secure note on your personal or organization vault with a section and settings for each environment you need.\r\n\r\n![Secure Note Example](resources/screenshots/op-note-appsettings.png)\r\n\r\nWith the following values:\r\n\r\n```csharp\r\nDatabase:ConnectionString: \"Data Source=(LocalDb)\\\\mssqllocaldb;Initial Catalog=local-org-database;Integrated Security=True\"\r\n```\r\n\r\nThen, the only thing we need to do is register an action to load the configuration values on our Program.cs. This way we will have our configuration values ready to use like with any appsettings.json:\r\n\r\n\r\n```csharp\r\n\r\n// Register configuration providers\r\n\r\nbuilder.Configuration\r\n    .AddJsonFile(\"appsettings.json\", optional: true, reloadOnChange: true)\r\n    .AddEnvironmentVariables();\r\n\r\nif (hostingContext.HostingEnvironment.IsDevelopment())\r\n{\r\n    // Register 1Password configuration provider following the Appy conventions with Appy 1Password Tool.\r\n    builder.Add1Password(\"Appy.Sample.1Password.Api\");\r\n}\r\n\r\n// Load App settings\r\n\r\nvar databaseSettings = new DatabaseSettings();\r\n\r\nvar databaseSettings = _config.GetSection(\"Database\").Bind(databaseSettings);\r\n\r\n... \r\n\r\n// Run App\r\nawait app.RunAsync();\r\n\r\npublic class DatabaseSettings\r\n{\r\n    public string ConnectionString { get; set; }\r\n}\r\n\r\n```\r\n\r\nThen would come the part where we communicate with 1Password and get these settings. We have created a command line tool that facilitates the process in a single command and allows you to create a session with some pre-configured settings. More on that below [Appy 1Password Tool](#appy-1password-tool).\r\n\r\nYou can find more examples on the samples folder.\r\n\r\n## Appy 1Password Tool\r\n\r\nThe Appy 1Password Tool is a dotnet tool that works as a wrapper around the official [1Password command-line tool](https://1password.com/downloads/command-line/). Following some basic conventions it will help you to start a 1Password session, so later you can run and debug locally any dotnet project using the preconfigured AppSettings saved on 1Password.\r\n\r\nThe tool allows you to create a session and later save the following information to be loaded by your project through the 1Password Configuration Provider extensions.\r\n\r\n#### Windows\r\n\r\nThe session information is stored in the next user's environment variables:\r\n\r\n```\r\n- APPY_OP_ORGANIZATION\r\n- APPY_OP_USERID\r\n- APPY_OP_VAULT\r\n- APPY_OP_ENVIRONMENT\r\n- APPY_OP_SESSION_TOKEN\r\n```\r\n\r\n* No password is stored on your machine, only the data of your session in your user environment variables.\r\n\r\n#### MacOs \u0026 Linux\r\n\r\nStoring environment variables globally on MacOS or Linux always seems complicated, and management varies a lot from one console to another. For this reason, the session information is store in a file (.appy-op-env) in the root folder of the current user.\r\n\r\nThe file will contain the following information:\r\n\r\n```\r\nAPPY_OP_ORGANIZATION=your organization\r\nAPPY_OP_USERID=your user id\r\nAPPY_OP_VAULT=Development\r\nAPPY_OP_ENVIRONMENT=DEV\r\nAPPY_OP_SESSION_TOKEN=1password session token\r\n```\r\n\r\n* No password is stored on your machine, only the data of your session.\r\n\r\n### Prerequisites\r\n#### Install 1Password CLI\r\n\r\nFirst, we should install the official [1Password CLI](https://support.1password.com/command-line/).\r\n##### Windows\r\n\r\nFor an easy installation, we recommend that you first install [Chocolatey Package Manager](https://chocolatey.org/install).\r\n\r\nOpen a Powershell console and install 1Password CLI:\r\n\r\n```console\r\nchoco install op --version=2.23.0\r\n```\r\n\r\n##### MacOS\r\n\r\nFor an easy installation, we recommend that you first install [Brew Package Manager](https://brew.sh/).\r\n\r\nOpen a console and install 1Password CLI using brew cask:\r\n\r\n```console\r\nbrew install --cask 1password/tap/1password-cli\r\n```\r\n\r\n##### Linux\r\n\r\nPlease, follow the official ['Getting started docs from 1Password'](https://support.1password.com/command-line-getting-started/)\r\n\r\n#### Disable Integration with Desktop App\r\n\r\nFor the AppyWay tool to work correctly when integrated with the 1Password CLI, the CLI integration with the desktop application must be disabled like in the next image.\r\n\r\n![Disable 1Password Desktop App CLI Integration](resources/screenshots/op-desktop-cli-integration-off.png)\r\n\r\nSteps:\r\n- Go to Settings\r\n- Click Developer\r\n- Unselect 'Integrate with 1Password CLI'\r\n\r\n### Installing\r\n\r\nInstall the tool globally.\r\n\r\n```console\r\ndotnet tool install -g appy-op\r\n```\r\n\r\n### Signin to 1Password\r\n\r\n#### First Time access\r\n\r\nExecute the next command to signin to 1Password and set the vault and environment to load:\r\n\r\n```console\r\nappy-op --signin \u003cyourorg\u003e \u003cemail-address\u003e \u003csecret_key\u003e --vault Development -env QA\r\n```\r\n\r\n*Note: make sure to use the Secret Key and not the Master Password*\r\n\r\nYou can get these data from your profile on the 1Password website.\r\n\r\nThen, it will ask for your Master Password.\r\n\r\nA normal session will look like this:\r\n\r\n```console\r\nappy-op --signin yourorg your_name@yourorg.com secretkey --vault Development -env QA\r\n\r\nEnter the password for your_name@yourorg.com at yourorg.1password.com:\r\n...\r\n\r\nUpdating 1Password session information.\r\n\r\nAppy 1Password session started:\r\n+------------------------------------------------------------+\r\n| Organisation | your org                                    |\r\n| UserId       | your user id                                |\r\n| Vault        | Development                                 |\r\n| Environment  | DEV                                         |\r\n| SessionToken | session token                               |\r\n+------------------------------------------------------------+\r\n\r\nYou can now go to your project and start your debug session.\r\nSession tokens expire after 30 minutes of inactivity, after which you'll need to sign in again.\r\n```\r\n\r\n#### Later time access\r\n\r\nFor subsequent accesses, it will only be necessary the next command:\r\n\r\n```console\r\nappy-op --signin (or -s)\r\n```\r\nor if you want to change the current vault or environment:\r\n\r\n```console\r\nappy-op -s -vt Custom -env DEV\r\n```\r\n\r\n### Auto-renew session activity\r\n\r\n1Password sessions have an expiration time of 30 min if there is no activity.\r\nNormally that will be enough, since during our project debug session, every time we\r\nload the project settings the session will be renewed for another 30 min.\r\n\r\nBut for cases where we are a bit lazy, or want to go outside for a long time and want to leave\r\nour session active, we have the option to signin with auto-renew. That will try to keep the session\r\nactive by making a simple random query to 1Password every 29 minutes.\r\n\r\n```console\r\nappy-op -s -a\r\n```\r\n\r\n### Nano Api and Docker\r\n\r\nIn search of supporting projects that could be executed inside Docker and at the same time consume the configuration from 1Password, a simple Nano Api integrated directly in the tool was added. This eliminates the need to have any reference to the 1Password cli in your project image.\r\n\r\n```console\r\nappy-op -s -a -api 5500\r\n```\r\n\r\nWhen executing or debugging your dotnet project in a Docker container, it will be necessary to specify the url of the tool's Api through an environment variable:\r\n\r\n```\r\nAPPY_OP_API_URI\r\n```\r\n\r\nIf this variable is set, the configuration requests are automatically redirected to the API instead of calling the 1Password cli directly from the project.\r\n\r\nAn example of execution could be the following:\r\n\r\n```console\r\ndocker run \\\r\n--env ASPNETCORE_ENVIRONMENT=Development \\\r\n--env APPY_OP_API_URI=http://host.docker.internal:5500/ \\\r\n--name appysample1passwordapi \\\r\ndev\r\n```\r\n\r\nWhere the url points to the special DNS name host.docker.internal which resolves to the internal IP address used by the host, where the tool will be running.\r\n\r\nThis option create an opportunity, where we can consume this api from projects in different programming languages.\r\n\r\n### Tool as Docker Image\r\n\r\nIn case you want to use the appy-op as a docker image and thus avoid installing the 1Password cli or any dotnet dependency on your system, you can use the next command to run the image.\r\n\r\n```console\r\ndocker run --rm -it -p 6000:6000 --name appy-op-test \\\r\nappyway/appy-op -s \u003cyourorg\u003e \u003cemail-address\u003e \u003csecret_key\u003e -vt Development -env DEV -a -api 6000\r\n```\r\n\r\nAnd to use appy-op with your host machine's existing config (or to persist configuration after the container exits):\r\n\r\nFirst time access:\r\n\r\n```console\r\ndocker run --rm -it -e \"HOME=$HOME\" -v \"$HOME:$HOME\" -p 6000:6000 --name appy-op-test \\\r\nappyway/appy-op -s \u003cyourorg\u003e \u003cemail-address\u003e \u003csecret_key\u003e -vt Development -env DEV -a -api 6000\r\n```\r\n\r\nLater time access:\r\n\r\n```console\r\ndocker run --rm -it -e \"HOME=$HOME\" -v \"$HOME:$HOME\" -p 6000:6000 --name appy-op-test \\\r\nappyway/appy-op -s -vt Development -env DEV -a -api 6000\r\n```\r\n\r\nOr you could create your own script and add it to the bin folder to simplify the process.\r\n\r\nTo communicate from your project with the tool, you could simply call the api as explained in the previous\r\nsection, or create a shared network between your projects and the tool.\r\n\r\n## Windows Registry Configuration Provider\r\n\r\nThe Windows registry has been with us for a long time and has served us well. Especially when we work locally or try to debug a project.\r\n\r\nWith this extension you can easily configure the loading of values from a section of your windows registry to your NETCore project configuration builder.\r\n\r\n### Installing\r\n\r\nInstall using the [Appy.Configuration.WinRegistry NuGet package](https://www.nuget.org/packages/Appy.Configuration.WinRegistry):\r\n\r\n```\r\nPM\u003e Install-Package Appy.Configuration.WinRegistry\r\n```\r\n\r\n### Usage\r\n\r\nWhen you install the package, it should be added to your _csproj_ file. Alternatively, you can add it directly by adding:\r\n\r\n```xml\r\n\u003cPackageReference Include=\"Appy.Configuration.WinRegistry\" Version=\"1.2.0\" /\u003e\r\n```\r\n\r\nNow let's imagine we have a configuration file like the following appSettings.json:\r\n\r\n```json\r\n\"Database\": {\r\n    \"ConnectionString\": \"\"\r\n}\r\n```\r\n\r\nAnd a user windows registry section like:\r\n\r\n```csharp\r\nHKEY_CURRENT_USER\\SOFTWARE\\YOUR_ORG\\Settings\r\n```\r\n\r\nWith the following values:\r\n\r\n```csharp\r\nDatabase:ConnectionString: \"Data Source=(LocalDb)\\\\mssqllocaldb;Initial Catalog=local-org-database;Integrated Security=True\"\r\n```\r\n\r\nThen, the only thing we need to do is register an action to load the configuration values on our Program.cs file. This way we will have our configuration values ready to use like with any appsettings.json:\r\n\r\n```csharp\r\nvar builder = WebApplication.CreateBuilder(args);\r\n\r\n// Register configuration providers\r\n\r\nbuilder.Configuration.AddJsonFile(\"appsettings.json\", optional: true, reloadOnChange: true);\r\n\r\nif (builder.Environment.IsDevelopment())\r\n{\r\n    builder.Configuration.AddRegistrySection(() =\u003e Microsoft.Win32.Registry.CurrentUser, \"Software\\\\YOUR_ORG\\\\Settings\");\r\n}\r\n\r\n// Load App settings\r\nvar databaseSettings = new DatabaseSettings();\r\n\r\nvar databaseSettings = builder.Configuration.GetSection(\"Database\").Bind(databaseSettings);\r\n\r\n...\r\n\r\n// Run App\r\nawait app.RunAsync();\r\n\r\npublic class DatabaseSettings\r\n{\r\n    public string ConnectionString { get; set; }\r\n}\r\n```\r\n\r\nTo switch between environments, we would have a registry key with the settings for each one, like:\r\n\r\n```\r\nQA   -\u003e \"Software\\\\YOUR_ORG\\\\QA_Settings\\\\Database:ConnectionString\"\r\nLIVE -\u003e \"Software\\\\YOUR_ORG\\\\LIVE_Settings\\\\Database:ConnectionString\"\r\n```\r\n\r\nThen we would only have to rename the registry environment folder key that we want to 'Settings',\r\nevery time we need it and return the previous one to its original name.\r\n\r\n```\r\nQA   -\u003e \"Software\\\\YOUR_ORG\\\\QA_Settings\" -\u003e rename -\u003e \"Software\\\\YOUR_ORG\\\\Settings\"      (We want to work with QA)\r\nLIVE -\u003e \"Software\\\\YOUR_ORG\\\\Settings\"    -\u003e rename -\u003e \"Software\\\\YOUR_ORG\\\\LIVE_Settings\" (LIVE back to his normal name)\r\n```\r\n\r\nApart of all these, we could then simply create an extension to load all our configurations in just one line,\r\nwith the windows registry configuration in Development and the rest of the appSettings configurations.\r\n\r\n```csharp\r\nvar builder = WebApplication.CreateBuilder(args);\r\n\r\n// Register configuration providers\r\nbuilder.Configuration.AddYourOrgAppConfiguration()\r\n\r\n...\r\n\r\n// Run App\r\nawait app.RunAsync();\r\n```\r\n\r\nThen, you can create some configuration extensions for your organization and override the config values in order. All these if necessary,\r\ncan be preconfigured in a nuget package for your organization, which each developer can use later in their projects.\r\n\r\n```csharp\r\npublic static class YourOrgConfigurationExtensions\r\n{\r\n    public static IConfigurationBuilder AddYourOrgRegistrySection(\r\n        this IConfigurationBuilder builder,\r\n        Action\u003cWinRegistryConfigurationSource\u003e configureSource = null)\r\n    {\r\n        return builder.AddRegistrySection(() =\u003e\r\n                Microsoft.Win32.Registry.CurrentUser, \"Software\\\\YOUR_ORG\\\\QA_Settings\");\r\n    }\r\n\r\n    public static IHostBuilder AddYourOrgAppConfiguration(this IHostBuilder hostBuilder)\r\n    {\r\n        hostBuilder.ConfigureAppConfiguration((hostingContext, config) =\u003e\r\n        {\r\n            config.AddYourOrgConfigurationBuilders(hostingContext.HostingEnvironment);\r\n        });\r\n\r\n        return hostBuilder;\r\n    }\r\n\r\n    public static IConfigurationBuilder AddYourOrgConfigurationBuilders(this IConfigurationBuilder builder, IHostEnvironment env)\r\n    {\r\n        builder\r\n            .AddJsonFile(\"appsettings.json\", optional: true, reloadOnChange: true)\r\n            .AddJsonFile($\"appsettings.{env.EnvironmentName}.json\", optional: true, reloadOnChange: true)\r\n            .AddEnvironmentVariables();\r\n\r\n        if (env.IsDevelopment())\r\n        {\r\n            builder.AddYourOrgRegistrySection();\r\n        }\r\n\r\n        return builder;\r\n    }\r\n}\r\n```\r\n\r\nYou can find more examples on the samples folder.\r\n\r\n## Contribute\r\nIt would be awesome if you would like to contribute code or help with bugs. Just follow the guidelines [CONTRIBUTING](https://github.com/YellowLineParking/Appy.Configuration/blob/master/CONTRIBUTING.md).\r\n\r\n## Additional Resources\r\n* [WinRegistry Configuration based on GeorgeTsaplin project](https://github.com/GeorgeTsaplin/Configuration.WinRegistry)","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fyellowlineparking%2Fappy.configuration","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fyellowlineparking%2Fappy.configuration","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fyellowlineparking%2Fappy.configuration/lists"}