agentsclimarketplace

Consent management

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

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.From its SKILL.md

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.

SKILL.md

5.3 KB, ~1.2k tokens by cl100k_base, 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.

What ships with it

Read from the repository

Just SKILL.md. No reference files, no scripts.

Keep looking

Skills are one crate of 325,949. 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.