SEE License Configuration Failure in .NET WebAPI with SQLite Encryption
Issue Overview: SEE License Validation Succeeds in Console App but Fails in .NET WebAPI with "Native Method Forbidden" Error
The core problem revolves around the SQLite Encryption Extension (SEE) license validation mechanism failing exclusively in a .NET WebAPI environment despite functioning correctly in a console application. The error System.NotSupportedException: {native method forbidden by license}
occurs at the SQLite3.SetPassword
method during database connection opening. This indicates that the SEE cryptographic routines – specifically those invoked during password-based encryption – are being blocked due to improper license configuration. The divergence between console and WebAPI execution contexts creates critical differences in how SEE license files are discovered, validated, and enforced.
In console applications, the working directory and assembly resolution paths typically align with the application’s binary output directory (<bin>
), allowing SEE license files placed in <bin>\Configurations\
to be detected automatically. WebAPI environments – particularly those hosted under IIS, Kestrel, or other web servers – introduce complexities:
- Runtime Directory Mismatch: The application’s effective working directory may differ from the physical
<bin>
path due to virtualization, shadow copying, or deployment layouts. - Security Context Restrictions: Web servers often execute under restricted user accounts (e.g.,
IIS AppPool\DefaultAppPool
) lacking filesystem permissions to access license files. - Build/Pipeline Artifact Exclusion: License files (
Harpy.v1.eagle
,Harpy.v1.eagle.b64sig
) might not be included in publish outputs or containerized deployments.
The SEE licensing subsystem requires both the license file and its Base64-encoded signature to be present in <bin>\Configurations\
with exact naming conventions. Failure to locate or read these files triggers a silent denial of cryptographic privileges, manifesting as the observed exception. This issue is aggravated by inconsistent documentation regarding SEE deployment in web-hosted scenarios and subtle differences between System.Data.SQLite’s native interop layer across application types.
Possible Causes: Missing or Misconfigured SEE License Files, Runtime Environment Discrepancies, and Permission Constraints
1. Incorrect License File Deployment Paths in WebAPI Builds
- Build Action Neglect: The
Harpy.v1.eagle
and.b64sig
files are not marked as "Content" or "Copy to Output Directory" in the WebAPI project, causing their absence in<bin>\Configurations\
post-compilation. - Publish Profile Oversights: Deployment pipelines (Azure DevOps, GitHub Actions) or IDE publish workflows might exclude non-code files from the output directory.
- Case Sensitivity Issues: Web servers on Linux/macOS hosts may enforce case-sensitive paths, rejecting
Configurations
vs.configurations
.
2. Runtime Environment Directory Structure Misalignment
- Shadow Copying in ASP.NET: IIS and ASP.NET Core may relocate assemblies to a temporary cache directory, breaking relative paths to
<bin>\Configurations\
. - Docker/Containerization Artifacts: Container filesystems often flatten directory hierarchies, omitting subdirectories like
Configurations
. - Framework-Dependent vs. Self-Contained Deployments: The
bin
directory structure varies between these modes, affecting file lookup.
3. Insufficient Filesystem Permissions for Web Server Identity
- AppPool/Service Account Access Rights: The Windows service account or Linux user running the WebAPI process might lack read permissions on
Configurations\
or its files. - ACL Inheritance Conflicts: Permission inheritance from parent directories could block access despite local settings.
4. SEE License Binding to Process Architecture or Hostname
- x86 vs. x64 Mismatch: If the SEE license was generated for a specific process architecture (e.g., x64), but the WebAPI runs as x86 (or vice versa), validation fails.
- Hostname Binding in License: Enterprise SEE licenses sometimes restrict usage to machines with specific hostnames, which may differ between development (console) and production (WebAPI) environments.
5. Antivirus/Endpoint Protection Interference
- Real-Time Scanning Blocking Access: Security software might quarantine or lock license files during read attempts by the WebAPI process.
Troubleshooting Steps, Solutions & Fixes: Validating License File Presence, Adjusting Deployment Workflows, and Configuring Runtime Permissions
Step 1: Verify License File Deployment in WebAPI Output Directory
- Manual Inspection: Navigate to the WebAPI’s published directory (e.g.,
\bin\Release\net7.0\publish
) and confirm thatConfigurations\Harpy.v1.eagle
andConfigurations\Harpy.v1.eagle.b64sig
exist. - Project File Configuration: In the
.csproj
file, ensure both files are included with:<ItemGroup> <Content Include="Configurations\Harpy.v1.eagle"> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> </Content> <Content Include="Configurations\Harpy.v1.eagle.b64sig"> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> </Content> </ItemGroup>
- Publish Profile Adjustments: For Azure Web Apps or Docker, add custom
<Copy>
tasks in.pubxml
to include theConfigurations
folder.
Step 2: Enforce Case-Sensitive Paths and Directory Structure
- Linux/macOS Hosts: Ensure directory names match case exactly (e.g.,
Configurations
, notconfigurations
). - Container Deployments: Use
RUN mkdir -p /app/Configurations
in Dockerfiles and verify file placement viaCOPY
.
Step 3: Grant Explicit Filesystem Permissions to Web Server Identity
- Windows:
icacls "C:\inetpub\wwwroot\MyWebApi\Configurations" /grant "IIS AppPool\DefaultAppPool:(RX)" icacls "C:\inetpub\wwwroot\MyWebApi\Configurations\Harpy.v1.eagle" /grant "IIS AppPool\DefaultAppPool:(R)"
- Linux:
chmod 755 /var/www/mywebapi/Configurations chmod 644 /var/www/mywebapi/Configurations/Harpy.v1.eagle* setfacl -R -m u:www-data:rX /var/www/mywebapi/Configurations
Step 4: Diagnose Shadow Copying and Runtime Path Resolution
- ASP.NET Core Hosting Model: Disable shadow copying via:
<PropertyGroup> <PreserveCompilationContext>true</PreserveCompilationContext> <AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects> <UseCommonOutputDirectory>true</UseCommonOutputDirectory> </PropertyGroup>
- Logging the Effective Working Directory: Inject
IHostEnvironment
or useDirectory.GetCurrentDirectory()
in startup to log the actual runtime path.
Step 5: Validate SEE License Compatibility with Host Environment
- Architecture Matching: Rebuild the WebAPI project to target the same architecture (x86/x64) as the console app.
- Hostname Verification: If the license is host-locked, ensure the WebAPI server’s hostname matches the console app’s development machine name.
Step 6: Exclude License Files from Antivirus Scanning
- Add exemptions in endpoint protection software for the
Configurations
directory and its contents.
Step 7: Programmatic License Initialization (Advanced)
For environments where file deployment is impractical, use the SQLiteLicense
class to apply the license programmatically:
SQLiteLicense.Register(() => File.ReadAllText("Configurations/Harpy.v1.eagle"));
Note: This requires the System.Data.SQLite.SEE
NuGet package and direct license string access.
Step 8: Enable SQLite and SEE Debug Logging
Add trace switches to appsettings.json
:
{
"System.Data.SQLite": {
"TraceLoad": true,
"TraceNativeMethods": true
}
}
This logs SEE initialization attempts and file access errors.
Final Validation
After applying fixes, test SEE functionality with a minimal connection attempt:
using (var conn = new SQLiteConnection("Data Source=encrypted.db;Password=secret"))
{
conn.Open(); // Should not throw
conn.Close();
}
By methodically addressing deployment paths, permissions, and environmental variables, the "native method forbidden by license" error can be resolved, enabling AES128 encryption in .NET WebAPI contexts.