Skip to content

Examples

This page provides complete, runnable examples for common go-phileas use cases.


Redact SSNs and email addresses

package main

import (
    "fmt"
    "github.com/philterd/go-phileas/pkg/policy"
    "github.com/philterd/go-phileas/pkg/services"
)

func main() {
    pol := &policy.Policy{
        Name: "redact-pii",
        Identifiers: policy.Identifiers{
            SSN: &policy.SSNFilter{
                SSNFilterStrategies: []policy.FilterStrategy{
                    {Strategy: policy.StrategyRedact, RedactionFormat: "{{{REDACTED-%t}}}"},
                },
            },
            EmailAddress: &policy.EmailAddressFilter{},
        },
    }

    svc, err := services.NewFilterService(pol)
    if err != nil {
        panic(err)
    }

    input := "Patient record: SSN 123-45-6789, contact jane@example.com."
    result, err := svc.Filter(pol, "patient-records", input)
    if err != nil {
        panic(err)
    }

    fmt.Println(result.FilteredText)
    // Output: Patient record: SSN {{{REDACTED-ssn}}}, contact {{{REDACTED-email-address}}}.
}

Mask credit card numbers, keep last 4

package main

import (
    "fmt"
    "github.com/philterd/go-phileas/pkg/policy"
    "github.com/philterd/go-phileas/pkg/services"
)

func main() {
    pol := &policy.Policy{
        Name: "mask-cards",
        Identifiers: policy.Identifiers{
            CreditCard: &policy.CreditCardFilter{
                OnlyValidCreditCardNumbers: true,
                CreditCardFilterStrategies: []policy.FilterStrategy{
                    {Strategy: policy.StrategyLast4},
                },
            },
        },
    }

    svc, err := services.NewFilterService(pol)
    if err != nil {
        panic(err)
    }

    input := "Charged card 4111111111111111 for the order."
    result, err := svc.Filter(pol, "payments", input)
    if err != nil {
        panic(err)
    }

    fmt.Println(result.FilteredText)
    // Output: Charged card *************1111 for the order.
}

Replace dates with a static placeholder

package main

import (
    "fmt"
    "github.com/philterd/go-phileas/pkg/policy"
    "github.com/philterd/go-phileas/pkg/services"
)

func main() {
    pol := &policy.Policy{
        Name: "anonymise-dates",
        Identifiers: policy.Identifiers{
            Date: &policy.DateFilter{
                DateFilterStrategies: []policy.FilterStrategy{
                    {Strategy: policy.StrategyStaticReplace, StaticReplacement: "[DATE]"},
                },
            },
        },
    }

    svc, err := services.NewFilterService(pol)
    if err != nil {
        panic(err)
    }

    input := "The appointment is on 2024-03-15 and the follow-up on April 2, 2024."
    result, err := svc.Filter(pol, "appointments", input)
    if err != nil {
        panic(err)
    }

    fmt.Println(result.FilteredText)
    // Output: The appointment is on [DATE] and the follow-up on [DATE].
}

Filter from a JSON policy string

package main

import (
    "fmt"
    "github.com/philterd/go-phileas/pkg/services"
)

func main() {
    policyJSON := `{
        "identifiers": {
            "phoneNumber": {
                "phoneNumberFilterStrategies": [
                    {"strategy": "STATIC_REPLACE", "staticReplacement": "[PHONE REMOVED]"}
                ]
            },
            "ipAddress": {}
        }
    }`

    input := "Server 192.168.0.1 received a call from 555-867-5309."
    result, err := services.FilterJSON(policyJSON, "network-logs", input)
    if err != nil {
        panic(err)
    }

    fmt.Println(result.FilteredText)
    // Output: Server {{{REDACTED-ip-address}}} received a call from [PHONE REMOVED].
}

Inspect spans returned with the result

package main

import (
    "fmt"
    "github.com/philterd/go-phileas/pkg/policy"
    "github.com/philterd/go-phileas/pkg/services"
)

func main() {
    pol := &policy.Policy{
        Name: "inspect",
        Identifiers: policy.Identifiers{
            SSN:          &policy.SSNFilter{},
            EmailAddress: &policy.EmailAddressFilter{},
        },
    }

    svc, err := services.NewFilterService(pol)
    if err != nil {
        panic(err)
    }

    input := "SSN 123-45-6789 and email john@example.com."
    result, err := svc.Filter(pol, "demo", input)
    if err != nil {
        panic(err)
    }

    fmt.Println("Filtered:", result.FilteredText)
    fmt.Printf("Found %d span(s):\n", len(result.Spans))

    for _, span := range result.Spans {
        fmt.Printf("  [%d:%d] type=%-20s original=%q replacement=%q\n",
            span.CharacterStart, span.CharacterEnd,
            span.FilterType, span.Text, span.Replacement)
    }
}

Output:

Filtered: SSN {{{REDACTED-ssn}}} and email {{{REDACTED-email-address}}}.
Found 2 span(s):
  [4:15]  type=ssn                  original="123-45-6789" replacement="{{{REDACTED-ssn}}}"
  [27:43] type=email-address        original="john@example.com" replacement="{{{REDACTED-email-address}}}"

Ignore specific terms

package main

import (
    "fmt"
    "github.com/philterd/go-phileas/pkg/policy"
    "github.com/philterd/go-phileas/pkg/services"
)

func main() {
    pol := &policy.Policy{
        Name: "with-ignore-list",
        Identifiers: policy.Identifiers{
            EmailAddress: &policy.EmailAddressFilter{
                BaseFilter: policy.BaseFilter{
                    Ignored: []string{"admin@example.com", "noreply@example.com"},
                },
            },
        },
    }

    svc, err := services.NewFilterService(pol)
    if err != nil {
        panic(err)
    }

    input := "Contact admin@example.com or the user at jane@example.com."
    result, err := svc.Filter(pol, "support", input)
    if err != nil {
        panic(err)
    }

    fmt.Println(result.FilteredText)
    // Output: Contact admin@example.com or the user at {{{REDACTED-email-address}}}.
}

Reuse a FilterService across multiple documents

package main

import (
    "fmt"
    "github.com/philterd/go-phileas/pkg/policy"
    "github.com/philterd/go-phileas/pkg/services"
)

func main() {
    pol := &policy.Policy{
        Name: "batch",
        Identifiers: policy.Identifiers{
            SSN:         &policy.SSNFilter{},
            PhoneNumber: &policy.PhoneNumberFilter{},
        },
    }

    // Build once, reuse many times.
    svc, err := services.NewFilterService(pol)
    if err != nil {
        panic(err)
    }

    documents := []struct {
        id   string
        text string
    }{
        {"doc-1", "SSN 123-45-6789"},
        {"doc-2", "Call 555-867-5309"},
        {"doc-3", "No sensitive data here"},
    }

    for _, doc := range documents {
        result, err := svc.Filter(pol, doc.id, doc.text)
        if err != nil {
            panic(err)
        }
        fmt.Printf("%s: %s\n", doc.id, result.FilteredText)
    }
}

Output:

doc-1: SSN {{{REDACTED-ssn}}}
doc-2: Call {{{REDACTED-phone-number}}}
doc-3: No sensitive data here

Comprehensive policy covering many identifier types

package main

import (
    "fmt"
    "github.com/philterd/go-phileas/pkg/policy"
    "github.com/philterd/go-phileas/pkg/services"
)

func main() {
    pol := &policy.Policy{
        Name: "comprehensive",
        Identifiers: policy.Identifiers{
            Age:           &policy.AgeFilter{},
            CreditCard:    &policy.CreditCardFilter{OnlyValidCreditCardNumbers: true},
            Date:          &policy.DateFilter{},
            EmailAddress:  &policy.EmailAddressFilter{},
            IPAddress:     &policy.IPAddressFilter{},
            MACAddress:    &policy.MACAddressFilter{},
            PhoneNumber:   &policy.PhoneNumberFilter{},
            SSN:           &policy.SSNFilter{},
            TrackingNumber: &policy.TrackingNumberFilter{},
            URL: &policy.URLFilter{
                RequireHTTPWWWPrefix: true,
            },
            VIN:     &policy.VINFilter{},
            ZipCode: &policy.ZipCodeFilter{},
        },
    }

    svc, err := services.NewFilterService(pol)
    if err != nil {
        panic(err)
    }

    input := `Patient is 45 years old. SSN: 123-45-6789. Email: patient@hospital.org.
Visit on 2024-03-15. IP: 10.0.0.1. Ship to ZIP 90210.
Track package 1Z999AA10123456784. Visit https://www.hospital.org.`

    result, err := svc.Filter(pol, "medical-record-001", input)
    if err != nil {
        panic(err)
    }

    fmt.Println(result.FilteredText)
}

Redact words from a custom dictionary

Use the Dictionaries identifier to redact specific words or phrases. This is useful for redacting project names, internal code words, or any domain-specific terms.

package main

import (
    "fmt"
    "github.com/philterd/go-phileas/pkg/policy"
    "github.com/philterd/go-phileas/pkg/services"
)

func main() {
    pol := &policy.Policy{
        Name: "dictionary-redaction",
        Identifiers: policy.Identifiers{
            Dictionaries: []policy.DictionaryFilter{
                {
                    Terms: []string{"Alice", "Bob", "Project Phoenix"},
                    DictionaryFilterStrategies: []policy.FilterStrategy{
                        {Strategy: policy.StrategyRedact, RedactionFormat: "{{{REDACTED-%t}}}"},
                    },
                },
            },
        },
    }

    svc, err := services.NewFilterService(pol)
    if err != nil {
        panic(err)
    }

    input := "Alice and Bob are working on Project Phoenix."
    result, err := svc.Filter(pol, "internal", input)
    if err != nil {
        panic(err)
    }

    fmt.Println(result.FilteredText)
    // Output: {{{REDACTED-custom-dictionary}}} and {{{REDACTED-custom-dictionary}}} are working on {{{REDACTED-custom-dictionary}}}.
}

The same policy in JSON:

{
  "identifiers": {
    "dictionaries": [
      {
        "terms": ["Alice", "Bob", "Project Phoenix"],
        "dictionaryFilterStrategies": [
          {"strategy": "REDACT", "redactionFormat": "{{{REDACTED-%t}}}"}
        ]
      }
    ]
  }
}

To load words from a file (one word per line), use the files field:

{
  "identifiers": {
    "dictionaries": [
      {
        "files": ["/etc/phileas/sensitive-names.txt"],
        "dictionaryFilterStrategies": [
          {"strategy": "STATIC_REPLACE", "staticReplacement": "[NAME REMOVED]"}
        ]
      }
    ]
  }
}