agentsclimarketplace

Consent management

Skill almasumdev/awesome-mobile-security-agent-skills/.github/skills/privacy/consent-management

Agent skills for securing mobile apps: storage, transport, auth, obfuscation, and hardening.

Install
npx -y skills add almasumdev/awesome-mobile-security-agent-skills --skill consent-management

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

2 things to look at

  • no licenseNo license file was found in the repository. Code published without one is not open source by default, so using it at work is a question for whoever answers licensing questions where you are.
  • 2 stars2 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

What its author says it does

Copied from the file, not written here

Platform consent frameworks on mobile — iOS App Tracking Transparency (ATT) and Android User Messaging Platform (UMP) for GDPR / CCPA. Use when integrating analytics, ads, or any cross-app tracking.

SKILL.md

5.3 KB, as published. Nobody here has run it

Consent Management on Mobile

Instructions

Consent on mobile has two dimensions: platform policy (App Store / Play rules) and regulatory (GDPR, CCPA, LGPD, PIPL). Both must pass.

1. iOS: App Tracking Transparency (ATT)

Required before you access the IDFA or perform cross-app/website tracking. The user sees a system prompt; only .authorized permits tracking.

import AppTrackingTransparency
import AdSupport

if #available(iOS 14.5, *) {
    ATTrackingManager.requestTrackingAuthorization { status in
        switch status {
        case .authorized:
            let idfa = ASIdentifierManager.shared().advertisingIdentifier
            AnalyticsSDK.enableTracking(idfa: idfa)
        case .denied, .restricted, .notDetermined:
            AnalyticsSDK.disableTracking()
        @unknown default: AnalyticsSDK.disableTracking()
        }
    }
}

Add a matching purpose string:

<key>NSUserTrackingUsageDescription</key>
<string>We use this to personalize ads you see in this app.</string>

Rules:

  • Ask at a moment the user understands, not at first launch before any context.
  • If the user denies, never re-prompt programmatically (Apple rejects this). They can re-enable in Settings.
  • If denied, disable all cross-app tracking, not just IDFA — fingerprinting workarounds violate App Store 5.1.1.

2. Android: Play Policy + UMP

Play Store requires a consent flow for EEA / UK users when you use personalized ads or non-essential tracking. Google's User Messaging Platform (UMP) is the common path:

val params = ConsentRequestParameters.Builder()
    .setTagForUnderAgeOfConsent(false)
    .build()

consentInformation = UserMessagingPlatform.getConsentInformation(this)
consentInformation.requestConsentInfoUpdate(
    this, params,
    {
        UserMessagingPlatform.loadAndShowConsentFormIfRequired(this) { err ->
            if (consentInformation.canRequestAds()) {
                initializeMobileAdsSdk()
            }
        }
    },
    { err -> /* network / config error — block ads until resolved */ },
)

Same principle: do not load ad SDKs until consent status is known.

3. Lawful Basis (GDPR) — Beyond Ads

Consent is one of six lawful bases; often not the right one.

ProcessingTypical lawful basis
Core feature (login, ordering)Contract
Security & fraud preventionLegitimate interest (documented)
Personalized ads / cross-site trackingConsent
Product analytics (aggregate)Legitimate interest or consent, depending on regulator
Marketing emailsConsent

Document the basis per processing purpose in your privacy policy. Do not default everything to "consent" — it's fragile and creates UX friction.

4. Consent UX Rules

  • Equal prominence for Accept and Reject buttons. No dark patterns.
  • "Reject all" must be as easy as "Accept all" (one tap).
  • No pre-ticked boxes.
  • The consent decision must be recorded (timestamp, version, user ID / install ID) for audit.
  • Support withdrawal: an always-reachable "Privacy Choices" screen in settings.

5. Per-Purpose Toggles

Use a Consent Management Platform (CMP) or roll your own ConsentStore:

type Purpose = 'analytics' | 'ads' | 'crash_reporting' | 'personalization';

interface ConsentRecord {
  purpose: Purpose;
  granted: boolean;
  recordedAt: string; // ISO
  version: string;    // policy version at time of consent
}

Every SDK initialization gates on the relevant purpose:

if (consent.granted('analytics')) Analytics.init();
if (consent.granted('crash_reporting')) Sentry.init();

Re-evaluate on every cold start; do not cache "we already initialized".

6. Minors

  • iOS: SKAdNetwork + ATT plus App Store age rating.
  • Android: setTagForUnderAgeOfConsent(true) where applicable; Play has strict Families policy.
  • Under-16 users in the EEA need parental consent for most non-essential processing.

7. CCPA / CPRA (California)

  • Honor a Global Privacy Control signal if your WebViews surface one.
  • Provide a clear "Do Not Sell or Share My Personal Information" link in the app (Settings / About).
  • "Sale" and "Share" are broader than cash sales — programmatic ads often qualify.

8. Audit Trail

  • Store every consent change with timestamp and policy version.
  • Be able to prove consent on demand to a regulator.
  • When the privacy policy materially changes, prompt again — silent updates don't carry consent.

Checklist

  • ATT is requested at a contextually appropriate moment with a clear purpose string.
  • Denied ATT disables all cross-app tracking, including fingerprinting.
  • UMP (or equivalent CMP) gates ad SDKs for EEA / UK users.
  • Lawful basis is documented per processing purpose — not defaulted to consent.
  • Accept / Reject have equal prominence; no pre-ticked boxes.
  • Per-purpose toggles gate SDK initialization on every launch.
  • Consent events are stored with timestamp + policy version, and withdrawable from Settings.
  • Privacy policy changes trigger re-prompting.

Keep looking

Skills are one crate of 328,083. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.