Skip to content

Core Walkthrough

This walks through masking a field with the Jackson backend (ihawu-jackson) alone — no web framework, just Jackson. On Spring Boot, the starter does all of this wiring for you; see Getting Started.

  1. Add the Jackson backend. It pulls ihawu-core transitively.

    implementation("org.ihawu:ihawu-jackson:0.4.1")
  2. Annotate the response type with the resource name policies resolve against.

    import org.ihawu.core.annotation.IhawuResource
    @IhawuResource("employee")
    data class EmployeeResponse(
    val id: String,
    val fullName: String,
    val salary: Double,
    val socialSecurityNumber: String,
    )
  3. Define the policies. Use the batteries-included static resolver, or implement the ResourcePolicyResolver SPI to pull rules from your own source. Either way you get a ResourcePolicyResolver to hand the module in the next step.

    import org.ihawu.core.masking.MaskingStrategy
    import org.ihawu.core.policy.FieldPolicy
    import org.ihawu.core.policy.ResourcePolicy
    import org.ihawu.core.policy.RoleBasedResourcePolicyResolver
    val resolver = RoleBasedResourcePolicyResolver(
    listOf(
    ResourcePolicy(
    resourceName = "employee",
    roleFieldPolicies = mapOf(
    "MANAGER" to listOf(
    FieldPolicy("socialSecurityNumber", MaskingStrategy.REDACT, "***-**-****"),
    ),
    ),
    ),
    ),
    )
  4. Register the Jackson module on your ObjectMapper.

    import com.fasterxml.jackson.databind.ObjectMapper
    import org.ihawu.jackson.IhawuModule
    val mapper = ObjectMapper().registerModule(IhawuModule(resolver))
  5. Serialize with the caller attached. Supply the IhawuPrincipal for the write via the IhawuSerialization.PRINCIPAL attribute; Ihawu masks per the resolved policy.

    import org.ihawu.core.policy.IhawuPrincipal
    import org.ihawu.jackson.IhawuSerialization
    val principal = IhawuPrincipal("u1", roles = setOf("MANAGER"), attributes = emptyMap())
    val employee = EmployeeResponse("42", "Jane Doe", 145_000.0, "123-45-6789")
    val json = mapper.writer()
    .withAttribute(IhawuSerialization.PRINCIPAL, principal)
    .writeValueAsString(employee)
    // socialSecurityNumber is now "***-**-****"; the other fields are untouched.

The Spring Boot starter handles the identity bridge, module registration, and request-scoped caching for you. The runnable sample shows the whole flow end to end against a live endpoint.