Skip to main content
Version: 3.x

Running an Application Offline Without a Fig Server

This guide walks through how to run a Fig-configured application without a Fig server while still protecting sensitive passwords — avoiding plain text secrets in appsettings.json.

Overview

The offline workflow has two phases:

  1. Generate — Run the application once with --printappsettings to produce an appsettings.fig.json file with encrypted secrets
  2. Run Offline — Rename the generated file to appsettings.json, then start the application with --figoffline; Fig reads configuration from appsettings.json and automatically decrypts any _FigEncrypted values

Prerequisites

  • Windows machine (DPAPI encryption is Windows-only)
  • The application must use Fig.Client and pass CommandLineArgs in FigOptions
  • The Fig.Client.SecretProvider.Dpapi NuGet package must be referenced and DpapiSecretProvider added to ClientSecretProviders
  • The same Windows user profile on the same machine must be used both to generate the file and to run the application

Step 1: Configure Your Application

Ensure your Program.cs (or equivalent startup code) passes the command line arguments to Fig. If you add a DpapiSecretProvider to ClientSecretProviders, DPAPI encryption is enabled automatically for both client secrets and appsettings generation — no extra property is needed:

var configuration = new ConfigurationBuilder()
.AddJsonFile("appsettings.json", optional: false) // Add BEFORE AddFig for offline reloads
.AddFig<MySettings>(o =>
{
o.ClientName = "My App";
o.CommandLineArgs = args; // Required for offline features
o.ClientSecretProviders = [new DpapiSecretProvider()]; // Enables DPAPI for client secrets and secret encryption/decryption
// ... other options
})
.Build();

DpapiSecretProvider is in the Fig.Client.SecretProvider.Dpapi package and implements both IClientSecretProvider and IAppSettingsEncryptionProvider. If no provider implementing IAppSettingsEncryptionProvider is found in ClientSecretProviders, secret settings are skipped during generation and not decrypted in offline mode.

And also update your IHostBuilder to support offline mode:

var host = Host.CreateDefaultBuilder(args)
.ConfigureAppConfiguration((_, config) =>
{
config.AddFig<MySettings>(o =>
{
o.ClientName = "My App";
o.CommandLineArgs = args;
o.ClientSecretProviders = [new DpapiSecretProvider()];
});
})
.UseFig<MySettings>()
// ...
.Build();

Step 2: Generate the appsettings.fig.json

Run your application with --printappsettings, providing values for any settings you want to override:

myapp.exe --printappsettings ApiUrl=https://api.company.com SecretFromSecureInput=<provide-at-runtime>
tip

Use a secure input or secret source for production secret values. Passing real secrets on the command line is not suitable for production because command-line arguments may be exposed by shell history, process listings, or command auditing.

tip

You must run this command as the same Windows user profile on the same machine that will run the application in production. DPAPI encryption is tied to both user identity and machine context.

The command will:

  1. Create appsettings.fig.json in the current working directory
  2. Print the file path to the console
  3. Exit immediately (the application does not start)

Example Output

{
"ApiUrl": "https://api.company.com",
"MaxRetries": "3",
"Password_FigEncrypted": "AQAAANCMnd8BFdERjH..."
}

Notice that Password appears as Password_FigEncrypted — the value is DPAPI-encrypted and tied to the Windows user profile and machine that generated it (unreadable by others). Do not commit production secrets to source control, even in encrypted form. For production environments, use file system permissions, an external secret manager, or environment variables to distribute this file securely.

Settings marked [Secret] are always stored encrypted. Other settings use their default values unless overridden.

Step 3: Run the Application Offline

Rename the generated appsettings.fig.json to appsettings.json and place it next to your application and start it with --figoffline:

myapp.exe --figoffline

When --figoffline is active, Fig:

  • Does not attempt to connect to the Fig API
  • Does not register or update settings
  • Does not start any background workers (health reporting, live reload, etc.)
  • Does scan the configuration for keys ending in _FigEncrypted
  • Does decrypt those values using DPAPI and make them available under their original names

Your application reads all other configuration (non-secret settings, environment variables, etc.) normally from appsettings.json and other standard configuration providers.

Comparison: --figoffline vs --disable-fig

Feature--figoffline--disable-fig=true
Connects to Fig API
Registers settings
Decrypts _FigEncrypted values
Uses standard config providers
Background workers

Use --figoffline when you have encrypted settings in appsettings.json. Use --disable-fig=true when you want to use standard configuration entirely without any Fig involvement.

Security Considerations

  • DPAPI-encrypted values are tied to the user profile on the machine where they were created
  • The encrypted value cannot be used on a different machine or by a different user
  • If you need to rotate the encrypted values (e.g., password changed), regenerate appsettings.fig.json using --printappsettings with the new value, then rename it to appsettings.json
  • Encrypted appsettings.json files are safer than plain text but should still be protected with appropriate file system permissions

Troubleshooting

Secret setting shows the default value instead of the configured one
Ensure that:

  • The application is running as the same Windows user profile on the same machine that generated the file
  • The _FigEncrypted key in appsettings.json is properly formed (no typos in the suffix)
  • The appsettings.json is in a location that the application reads from

Settings are not being read from appsettings.json
The application's startup must add appsettings.json as a configuration source before calling AddFig<T>(). Example:

var configuration = new ConfigurationBuilder()
.AddJsonFile("appsettings.json", optional: false) // Add BEFORE AddFig
.AddFig<MySettings>(o =>
{
o.ClientName = "My App";
o.CommandLineArgs = args;
})
.Build();

--printappsettings generates no secret entries on Linux/macOS
DPAPI is only available on Windows, and DPAPI-encrypted files are valid only for the same Windows user profile on the same machine. Do not transfer a DPAPI-generated offline settings file to another machine or a Linux/macOS target. For cross-machine or non-Windows deployments, use a non-DPAPI secret strategy such as Docker secrets or cloud secret providers (see Client Secret Providers).