dotkit 1.1.0
dotnet tool install --global dotkit --version 1.1.0
This package contains a .NET tool you can call from the shell/command line.
dotnet new tool-manifest
dotnet tool install --local dotkit --version 1.1.0
This package contains a .NET tool you can call from the shell/command line.
#tool dotnet:?package=dotkit&version=1.1.0
The NuGet Team does not provide support for this client. Please contact its maintainers for support.
nuke :add-package dotkit --version 1.1.0
The NuGet Team does not provide support for this client. Please contact its maintainers for support.
dotkit
A .NET CLI tool that installs and configures JWT Authentication in ASP.NET Core Web API projects with a single command.
Features
- Supports .NET 6 and later: multi-targeted tool (
net6.0,net8.0,net10.0) that installs and runs on any .NET 6+ runtime - Detects the target project's target framework and rejects frameworks older than .NET 6
- Installs
Microsoft.AspNetCore.Authentication.JwtBearerNuGet package with the version matched to the project's target framework (resolved from NuGet, e.g.6.0.xfornet6.0) - Adds
Jwtsection toappsettings.jsonwith auto-generated secret key - Creates
JwtSettingsandJwtServiceready-to-use classes (C# 10 compatible, so they compile onnet6.0) - Injects JWT authentication, DI registration, and middleware into
Program.cs - Configures User Secrets for
SecretKey,Issuer, andAudience(or writes them toappsettings.jsonvia--no-user-secrets) - Logs progress to console and rolling files via Serilog
Installation
dotnet tool install --global dotkit
Usage
dotkit install [options]
Options
| Option | Description | Default |
|---|---|---|
--project |
Path to the Web API project directory | Current directory |
--secret-key |
JWT secret key (32+ chars) | Auto-generated (64 chars base64) |
--issuer |
Token issuer | Project name |
--audience |
Token audience | Project name |
--no-user-secrets |
Write values to appsettings.json instead of User Secrets |
false |
--verbose |
Enable debug-level logging | false |
Examples
# Default: stores values in User Secrets
dotkit install
# Custom values
dotkit install --project ./MyApi --issuer "MyApp" --audience "MyApp"
# Write values directly to appsettings.json (skip User Secrets)
dotkit install --no-user-secrets --secret-key "your-32-char-min-key-here..."
What it does
- Detects the ASP.NET Core Web API project (must target
Microsoft.NET.Sdk.Weband .NET 6.0 or later) - Installs
Microsoft.AspNetCore.Authentication.JwtBearerNuGet package (version matched to the project's target framework) - Merges
Jwtsection intoappsettings.json - Creates
Configuration/JwtSettings.csandServices/JwtService.cs - Injects into
Program.cs:- Required
usingdirectives builder.Services.AddAuthentication().AddJwtBearer()withTokenValidationParametersbuilder.Services.Configure<JwtSettings>(...)builder.Services.AddScoped<JwtService>()app.UseAuthentication()andapp.UseAuthorization()
- Required
- Configures
SecretKey,Issuer, andAudiencevia User Secrets (orappsettings.json)
After running, inject JwtService in any controller and call GenerateAccessToken() to issue JWTs.
Secret storage modes
| Mode | appsettings.json |
User Secrets |
|---|---|---|
| User Secrets (default) | Placeholder (CHANGE_ME...) |
Real key, issuer, audience |
--no-user-secrets |
Real key, issuer, audience | Not configured |
Lifecycle
dotkit install [options]
│
▼
┌─────────────────────┐
│ Initialize Serilog │ → %TEMP%\dotkit\logs\dotkit-YYYYMMDD.log
└─────────┬───────────┘
▼
┌─────────────────────┐
│ ProjectDetector │ ← Reads .csproj from directory
│ .Detect() │
└─────────┬───────────┘
▼
┌─────────────────────┐
│ JwtInstaller │ ← dotnet add package
│ .InstallAsync() │ Microsoft.AspNetCore.Authentication.JwtBearer
└─────────┬───────────┘
▼
┌─────────────────────┐
│ JsonEditor │ ← Merges Jwt section from template
│ .UpdateAppSettings │ into existing appsettings.json
│ (key?,iss?,aud?) │ (real values if --no-user-secrets,
└─────────┬───────────┘ placeholder if User Secrets)
▼
┌─────────────────────┐
│ TemplateInstaller │ ← Creates:
│ .InstallTemplates │ Configuration/JwtSettings.cs
│ │ Services/JwtService.cs
└─────────┬───────────┘
▼
┌─────────────────────┐
│ ProgramEditor │ ← Injects into Program.cs:
│ .UpdateProgramAsync│ - usings for .Configuration and .Services
│ │ - AddAuthentication + AddJwtBearer
│ │ - Configure<JwtSettings>
│ │ - AddScoped<JwtService>
│ │ - app.UseAuthentication/Authorization
└─────────┬───────────┘
▼
┌─────────────────────┐
│ UserSecretsManager │ ← (only if NOT --no-user-secrets)
│ .ConfigureAsync │ dotnet user-secrets init
│ │ set Jwt:SecretKey
│ │ set Jwt:Issuer
│ │ set Jwt:Audience
└─────────┬───────────┘
▼
✓ Installation completed successfully
Possible errors
ProjectDetector
| Error | Cause |
|---|---|
Directory '{path}' not found. |
--project points to a non-existent directory |
No .csproj file was found. |
Directory contains no .csproj file |
Program.cs was not found. |
Project has no Program.cs |
The selected project is not an ASP.NET Core Web API. |
.csproj doesn't use Microsoft.NET.Sdk.Web |
JsonEditor
| Error | Cause |
|---|---|
Template not found: {path} |
appsettings.json template missing from Templates/ |
Template JSON is invalid. |
Template is not valid JSON |
Template does not contain 'Jwt' section. |
Template has no Jwt property |
Existing appsettings.json contains invalid JSON. |
Target project's appsettings.json has malformed JSON |
JwtInstaller
| Error | Cause |
|---|---|
Failed to install Microsoft.AspNetCore.Authentication.JwtBearer: ... |
dotnet add package failed (no connection, incompatible version, etc.) |
UserSecretsManager
| Error | Cause |
|---|---|
Error: dotnet user-secrets init --project ... |
Could not initialize User Secrets (permissions, SDK) |
Error: dotnet user-secrets set --project ... |
Could not set a secret |
Runtime errors (in the generated project, NOT in the tool)
| Error (project runtime) | Cause |
|---|---|
JWT settings not configured. |
Jwt section in appsettings.json was not loaded correctly |
IDX10720: key size must be greater than '256' bits |
SecretKey < 32 characters (only if someone modified the placeholder) |
SecretKey not found. / Issuer not found. / Audience not found. |
JwtService instantiated without configured values |
Exit code
0→ success1→ any error (message and exception are logged)
Requirements
- A .NET runtime 6.0 or later to install and run the
dotkittool - An ASP.NET Core Web API project targeting
net6.0or later (net6.0,net8.0,net10.0, ...)
The tool is multi-targeted (net6.0, net8.0, net10.0) and the installer picks the binary that matches the runtime available on your machine.
Supported target projects
- Target framework:
net6.0or later. Older frameworks (net5.0,netcoreapp3.1,netstandard2.0) are rejected. - The
Microsoft.AspNetCore.Authentication.JwtBearerversion is resolved automatically from the target project's framework (e.g.6.0.xfornet6.0,8.0.xfornet8.0), using the latest stable version for that line. - Generated templates (
JwtSettings.cs,JwtService.cs) are compatible with C# 10, so they compile innet6.0projects.
CI/CD & Releases
The repository uses GitHub Actions with a supply-chain hardened setup:
.github/workflows/ci.yml— runs on push tomain/devand on PRs: build (all 3 TFMs), unit tests, NuGet vulnerability audit (dotnet list package --vulnerable), pack, and an end-to-end smoke test (scripts/e2e.sh) that installs the packed tool and verifies/tokenand/protectedbehavior onnet6.0,net8.0, andnet10.0samples..github/workflows/release.yml— publishes to NuGet.org using Trusted Publishing (OIDC): no long-lived API keys. It requests a short-lived API key at push time viaNuGet/login@v1and uses--skip-duplicate.- Actions are pinned to commit SHAs and kept updated by Dependabot (
.github/dependabot.yml). global.jsonpins the .NET SDK (10.0.302) for reproducible builds;ContinuousIntegrationBuildenables deterministic packaging in CI.- Permissions are least-privilege (
contents: read,id-token: writeonly on the publish job) andpersist-credentials: false.
How to publish a release
- One-time setup:
- nuget.org → your account → Trusted Publishing → add a policy for owner
Gianss19, repositorydotkit, workflow filerelease.yml. - GitHub repo → Settings → Secrets and variables → Actions → add
NUGET_USER= your nuget.org username (profile name, not email).
- nuget.org → your account → Trusted Publishing → add a policy for owner
- Trigger a publish:
- Manually: Actions → Release → Run workflow → enter
version(e.g.1.1.0). - Or push a tag:
git tag v1.2.0 && git push origin v1.2.0. The version is validated against a SemVer regex before packaging.
- Manually: Actions → Release → Run workflow → enter
Development
Clone the repository and build, test, and pack locally:
git clone https://github.com/Gianss19/dotkit.git
cd dotkit
# Build all target frameworks (net6.0, net8.0, net10.0)
dotnet build
# Run the unit tests
dotnet test tests/dotkit.Tests.csproj
# Audit NuGet packages for known vulnerabilities
dotnet list dotkit.csproj package --vulnerable --include-transitive
# Pack the NuGet tool package
dotnet pack -c Release -o artifacts
# End-to-end smoke test (needs a bash shell; uses the packed nupkg in artifacts/)
bash scripts/e2e.sh
Contributing
Contributions are welcome! To report a bug, request a feature, or open a pull request, use the repository's issue tracker:
- Repository: https://github.com/Gianss19/dotkit
- Issues: https://github.com/Gianss19/dotkit/issues
- Pull requests: https://github.com/Gianss19/dotkit/pulls
License
This project is licensed under the MIT License.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net6.0 is compatible. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. 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 was computed. 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.
This package has no dependencies.