Getting Started
This guide walks you through adding phileas-dotnet to a .NET project and running your first PII filter.
Prerequisites
- .NET 10 or later
- A project that references the
PhileasNuGet package or project
Installation
Add the NuGet package to your project:
dotnet add package Phileas
Or add a project reference directly:
<ProjectReference Include="../src/Phileas/Phileas.csproj" />
Basic Usage
1. Define a Policy
A Policy describes which PII types to detect and how to handle them.
using Phileas.Policy;
using Phileas.Policy.Filters;
var policy = new Policy
{
Name = "basic-policy",
Identifiers = new Identifiers
{
Ssn = new Ssn(),
EmailAddress = new EmailAddress(),
PhoneNumber = new PhoneNumber()
}
};
By default, all detected PII is redacted (replaced with {{{REDACTED-<type>}}}).
2. Filter Text
Create an instance of FilterService and call Filter with the policy, a context name, a piece index, and the input text:
using Phileas.Services;
var result = new FilterService().Filter(
policy,
context: "session-1",
piece: 0,
input: "SSN: 123-45-6789 Email: alice@example.com Phone: 555-867-5309"
);
Console.WriteLine(result.FilteredText);
// SSN: {{{REDACTED-ssn}}} Email: {{{REDACTED-email-address}}} Phone: {{{REDACTED-phone-number}}}
3. Inspect the Results
FilterService.Filter returns a TextFilterResult that contains the filtered text and a list of Span objects describing each detected PII occurrence:
foreach (var span in result.Spans)
{
Console.WriteLine($"[{span.CharacterStart}–{span.CharacterEnd}] {span.FilterType}: \"{span.Text}\" → \"{span.Replacement}\"");
}
Customising the Redaction Format
Each filter type supports a custom redactionFormat. Use %t as a placeholder for the filter type name:
using Phileas.Policy.Filters;
using Phileas.Policy.Filters.Strategies;
var policy = new Policy
{
Name = "custom-format",
Identifiers = new Identifiers
{
Ssn = new Ssn
{
Strategies = new List<SsnFilterStrategy>
{
new SsnFilterStrategy
{
Strategy = "REDACT",
RedactionFormat = "[REMOVED-%t]"
}
}
}
}
};
Loading a Policy from JSON
Policies can be serialised as JSON and deserialised at runtime. Use PolicySerializer rather than System.Text.Json directly — it applies the canonical serialization options (null omission) and resolves ${ENV_VAR} placeholders against environment variables:
using Phileas.Policy;
const string json = """
{
"identifiers": {
"ssn": {},
"emailAddress": {}
}
}
""";
var policy = PolicySerializer.DeserializeFromJson(json);
// And back to JSON:
string serialized = PolicySerializer.SerializeToJson(policy);
The canonical policy JSON has no top-level
namefield — the policyNameis an in-memory label only and is not serialized. Policies can also be authored in PhiSQL and compiled withPolicy.FromPhiSQL(phisql).
Using Conditional Strategies
Apply different strategies based on context, confidence, or the detected token value:
using Phileas.Policy.Filters.Strategies;
var policy = new Policy
{
Name = "conditional-policy",
Identifiers = new Identifiers
{
EmailAddress = new EmailAddress
{
Strategies = new List<EmailAddressFilterStrategy>
{
// Fully redact emails in medical context
new EmailAddressFilterStrategy
{
Strategy = "REDACT",
Condition = "context == \"medical\""
},
// Mask emails in other contexts
new EmailAddressFilterStrategy
{
Strategy = "MASK"
}
}
}
}
};
// Medical context - email will be redacted
var medicalResult = new FilterService().Filter(policy, "medical", 0, "Contact: john@example.com");
// Output: "Contact: {{{REDACTED-email-address}}}"
// Other context - email will be masked
var defaultResult = new FilterService().Filter(policy, "default", 0, "Contact: john@example.com");
// Output: "Contact: ****************"
See Filter Conditions for detailed examples and advanced usage.
Running the Tests
dotnet test tests/Phileas.Tests/Phileas.Tests.csproj
Next Steps
- Policies — configure policy options such as window size and ignored values
- Supported Identifiers — full list of built-in PII types
- Filter Strategies — choose how PII is replaced
- Filter Conditions — apply strategies conditionally
- Context Service — keep random replacements consistent across calls