Skip to main content

Release-gate linter that checks Luciq-SDK apps for PII-masking gaps (iOS + Android).

Project description

Luciq PII Masking Linter

Catches unmasked PII — card numbers, SSNs, emails, passwords — in your Luciq-SDK app before it ships, across screenshots, Session Replay, and network logs. Use it in your editor, in CI, or as a release gate.

Works for iOS (Swift) and Android (Kotlin/Java).

Install for: Android · iOS — each covers local + CI.


Install

Android

Native Android Lint, distributed via JitPack — no Python needed.

1. Add JitPack to settings.gradle.kts:

dependencyResolutionManagement {
    repositories {
        google()
        mavenCentral()
        maven { url = uri("https://jitpack.io") }   // ← add this
    }
}

2. Add the check to app/build.gradle.kts:

dependencies {
    lintChecks("com.github.luciqai:luciq-masking-lint:0.1.1")
}

3. Run it:

./gradlew :app:lint

Unmasked PII is now a red Lint error — a squiggle in Android Studio as you type, and a failed build in CI. It reads your project's luciq.yml (compliance level + custom keywords) — the same file the CLI uses. Control blocking vs. report-only in Lint settings.

On Maven Central instead? Use ai.luciq:luciq-masking-lint:0.1.1 and drop the JitPack line.

iOS

Install the command-line tool (Python 3.8+, no other dependencies). Use pipx so the command lands in ~/.local/bin — a stable location the Xcode build can find:

pipx install luciq-masking-linter

To see findings inline in Xcode, add a Run Script build phase. Xcode build phases run with a minimal PATH, so add ~/.local/bin before calling the command — otherwise the build reports it as "not installed" even when it is:

export PATH="$HOME/.local/bin:$PATH"
luciq-masking-linter "$SRCROOT" --format xcode --mode warn

CI / other

Install the tool, then run it where you want a gate. GitHub Actions:

- uses: actions/setup-python@v5
- run: pip install luciq-masking-linter
- run: luciq-masking-linter . --mode enforce      # fails the job on a gap

Any CI works the same: install, then luciq-masking-linter . --mode enforce.

  • Inline PR annotations: --format github · GitHub Code Scanning: --format sarif.
  • Android CI can skip Python and just run ./gradlew :app:lint.

Tuning the linter

How you control the linter — blocking vs. report-only, output format, what to skip — depends on your platform, but the goal is the same. Jump to yours:

Compliance level and exclude always come from luciq.yml — shared by both platforms.

iOS / CI — command-line flags

The luciq-masking-linter command takes a path to scan plus a few flags.

luciq-masking-linter [path] --mode enforce --compliance gdpr --format sarif
Flag Default What it does
--mode warn warn reports and exits 0; enforce exits 1 on a blocking gap (the gate)
--compliance from luciq.yml none / soc2 / pci / gdpr / hipaa — overrides the file
--format text text, xcode (inline in Xcode), github (PR annotations), sarif (Code Scanning)
--exclude a path or glob to skip (repeatable)

A run looks like:

[FAIL] unmasked-field PaymentView.swift:24 — card field is not masked …
[warn] unmasked-field ProfileView.swift:31 — phone field is not masked …
Summary: 1 fail, 1 warn   →   BLOCK release

Android — Lint settings

Out of the box the check blocks: ./gradlew :app:lint (and CI) fail on a masking gap. You tune it in app/build.gradle.kts, inside android { lint { … } }.

Most common: show findings as warnings only (squiggles, but never fail the build).

android {
    lint {
        warning += "LuciqUnmaskedPii"     // demote the two blocking checks…
        warning += "LuciqMaskingConfig"   // …to non-blocking warnings
    }
}

That's it — you still get the editor squiggles and report entries, but the build stays green.

Other knobs, same lint { } block:

Want to… Add this
turn a check off completely disable += "LuciqUnmaskedPii"
keep errors but don't fail the build (project-wide) abortOnError = false
block only new findings baseline = file("lint-baseline.xml")
write SARIF for GitHub Code Scanning sarifReport = true

The four issue ids (use them in warning += / disable += above):

Issue id Default What it covers
LuciqUnmaskedPii error (blocks) an unmasked PII field
LuciqMaskingConfig error (blocks) project posture: auto-mask, network, FLAG_SECURE, consent, old SDK
LuciqUnmaskedPiiAdvisory warning advisory field finding
LuciqMaskingConfigAdvisory warning advisory posture finding

Skip a finding

If a flagged field isn't really PII, skip it with a comment:

  • // luciq-mask-ignore on the field's line (or the line just above it).
  • // luciq-mask-ignore-file anywhere in a file to skip that whole file.
  • Add a reason for the audit trail: // luciq-mask-ignore: masked upstream.

Card fields can't be skipped under pci.


Configure — luciq.yml (optional)

Put one file at your project root. It holds the handful of things the linter can't read from your code. Both the CLI and the Android Lint check read it.

pii_masking:
  compliance: gdpr               # none | soc2 | pci | gdpr | hipaa
  keywords:                      # your app-specific PII field names
    account: [loyaltyId, membershipNo]
  exclude: [app/generated]       # paths to skip

Compliance levels — what blocks vs. warns

Level Blocks on
none / soc2 card, SSN, credentials
pci same, and card waivers are refused
gdpr + email, phone, name, address, DOB, every text input; consent required
hipaa all of the above + health; MEDIA auto-mask + consent required

Exit codes

0 = clean, or --mode warn. 1 = --mode enforce and a blocking gap.

On Android, ./gradlew :app:lint fails the build on a blocking gap the same way — unless abortOnError = false.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

luciq_masking_linter-0.1.1.tar.gz (17.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

luciq_masking_linter-0.1.1-py3-none-any.whl (14.4 kB view details)

Uploaded Python 3

File details

Details for the file luciq_masking_linter-0.1.1.tar.gz.

File metadata

  • Download URL: luciq_masking_linter-0.1.1.tar.gz
  • Upload date:
  • Size: 17.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for luciq_masking_linter-0.1.1.tar.gz
Algorithm Hash digest
SHA256 14fef67237a44051ace69a0775c4672a587941364a3dbbbee2b71e09cbc9ecf9
MD5 833df1cb41b540840261119bb298b50a
BLAKE2b-256 24443313e72d579749a2679bf065b39da92443836b05a81b4e6b94f5487d33ff

See more details on using hashes here.

Provenance

The following attestation bundles were made for luciq_masking_linter-0.1.1.tar.gz:

Publisher: release-pypi.yml on luciqai/luciq-masking-linter

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file luciq_masking_linter-0.1.1-py3-none-any.whl.

File metadata

File hashes

Hashes for luciq_masking_linter-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 9cdfe926ba0a1864e80a62ccb459cc3c0a39e6357359ce2c06b8809f2dd26f96
MD5 2639737c3ce94bf544700c5ce3b39d90
BLAKE2b-256 261b635df070b1c4702bb61313f2c20fbcce0efe88c05b3b96efaa2534a1f60c

See more details on using hashes here.

Provenance

The following attestation bundles were made for luciq_masking_linter-0.1.1-py3-none-any.whl:

Publisher: release-pypi.yml on luciqai/luciq-masking-linter

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page