Legal Age App Logo ID & Face Verification

Legal Age — ID & Face Verification (Flutter)

Legal Age is a modern, agency-ready mobile app to verify legal age and confirm identity by comparing an ID photo to a live selfie. The app supports dual cloud providers (AWS + Azure) with automatic failover, keeping secrets on the server side for security and compliance.

Use Case

Legal-age gating, KYC-lite, regulated content and commerce.

Tech Stack

Flutter · Firebase (optional) · AWS Rekognition · Azure Face API

Pricing

Serious offers only – includes app, backend patterns and documentation.

Features

Everything you need for age & ID verification in one Flutter app.

📸 Capture & Match

  • ID + selfie capture via device camera.
  • Face match between ID face and live selfie.
  • Legal-age decision (18/21/custom) with clear messaging.

🤖 Cloud Intelligence

  • AWS Rekognition: CompareFaces & DetectFaces.
  • Azure Face API: verify & detect?returnFaceAttributes=age.
  • Age estimation with confidence scores.

🧠 Automatic Failover

  • Primary provider preference (AWS or Azure).
  • Automatic fallback on network/HTTP/parse errors.
  • UI shows which provider handled the final result.

🎨 Agency-Ready UI

  • Material 3, high contrast, dark mode.
  • Step-by-step flows with clear statuses.
  • Results summaries and explanatory text for edge cases.

⚙️ Runtime Settings

  • Switch primary provider at runtime.
  • Override API bases/keys and auth headers.
  • Configure legal-age threshold; persisted via SharedPreferences.

🔐 Security First

  • Server-side secrets; app only talks to your proxies.
  • Optional auditing hooks (e.g., Firestore logs).
  • Clear guidance for JWT protection and data retention.

Architecture Overview

Clean separation between Flutter app, proxy services, and cloud providers.

Mobile (Flutter)

  • main.dart — app entry, global error handling, theming.
  • id_scanner_app.dart — shell with a private navigator.
  • id_scanner_home_page.dart — home with quick actions.
  • main_screen.dart — guided overview and entry to verification.
  • face_verification_screen.dart — capture, verify, results.
  • settings_screen.dart — provider, threshold, and runtime overrides.

Backends (Server-Side)

  • AWS Lambda + API Gateway for Rekognition.
  • Azure Functions for Azure Face API.
  • Both expose normalized JSON for the Flutter app.

Data Flow

Camera (ID & Selfie) → Flutter App → Your Proxy API (AWS or Azure). On failure, the orchestrator falls back to the secondary provider and returns normalized results: { matched, confidence, estimatedAge, ageConfidence, provider }.

Getting Started

Prerequisites

  • Flutter 3.19+.
  • Xcode (iOS) and Android SDK (Android).
  • AWS and/or Azure accounts for backends.

Core Dependencies

dependencies:
  flutter:
    sdk: flutter
  http: ^1.2.2
  image_picker: ^1.1.2
  google_fonts: ^6.2.1
  shared_preferences: ^2.3.2
          

Runtime Configuration

Environment-agnostic builds using --dart-define and runtime overrides.

Dart Define Example Purpose
AWS_API_BASE https://abc.execute-api.us-east-1.amazonaws.com/prod API Gateway base URL for AWS Lambdas.
AZURE_FN_BASE https://your-fn.azurewebsites.net Azure Function App base URL.
AZURE_FN_CODE ... (optional) Function key if required by your auth level.
AUTH_BEARER eyJhbGciOiJI... JWT/ID token header for your gateways (optional).
PRIMARY_PROVIDER aws or azure Default provider preference.

All of these can be overridden at runtime via the Settings screen and persisted using SharedPreferences.

Platform Permissions

iOS — Info.plist

<key>NSCameraUsageDescription</key>
<string>Camera is used to capture ID photos and selfies for verification.</string>
<key>NSPhotoLibraryUsageDescription</key>
<string>Photo library access is used to pick images for verification.</string>
          

Deploying the Backends

AWS + Azure patterns ready for your infrastructure team.

AWS: Rekognition + Lambda + API Gateway

IAM Role policy (Lambda):

{
  "Version": "2012-10-17",
  "Statement": [
    {"Effect":"Allow","Action":["rekognition:CompareFaces","rekognition:DetectFaces"],"Resource":"*"},
    {"Effect":"Allow","Action":["s3:GetObject"],"Resource":"*"}
  ]
}
            
  • Create two Node.js 20 Lambdas: POST /compare, POST /detect.
  • Wire them via an HTTP API in API Gateway with CORS enabled.
  • Use multipart form-data: idImage, selfieImage, or image.

Sample tests:

curl -X POST "$AWS_API_BASE/compare" \
  -F idImage=@id.jpg -F selfieImage=@selfie.jpg

curl -X POST "$AWS_API_BASE/detect" \
  -F image=@selfie.jpg
            

Build & Run

Development

flutter pub get

flutter run \
  --dart-define=AWS_API_BASE=https://abc.execute-api.us-east-1.amazonaws.com/prod \
  --dart-define=AZURE_FN_BASE=https://your-fn.azurewebsites.net \
  --dart-define=PRIMARY_PROVIDER=aws
          

Android Release

flutter build apk --release \
  --dart-define=AWS_API_BASE=... \
  --dart-define=AZURE_FN_BASE=... \
  --dart-define=PRIMARY_PROVIDER=aws
# or:
# flutter build appbundle --release ...
          

iOS Release

flutter build ios --release \
  --dart-define=AWS_API_BASE=... \
  --dart-define=AZURE_FN_BASE=... \
  --dart-define=PRIMARY_PROVIDER=azure
# Then archive/sign in Xcode as usual
          

Testing & QA

Happy Path

  • Clear ID and selfie of the same person → matched=true, high confidence.
  • Plausible age from selfie with confidence metrics.

Fallback Scenarios

  • Temporarily disable one backend → expect successful result via the other.
  • UI clearly indicates “Fallback used”.

Edge Cases

  • No face detected → matched=false, estimatedAge=null.
  • Multiple faces → first face used; prompt user to retake.
  • Poor lighting / occlusions → lower confidence but safe messaging.

Troubleshooting

  • AWS_API_BASE / AZURE_FN_BASE empty: Set via --dart-define or Settings.
  • 403/401: Check AZURE_FN_CODE or JWT auth.
  • CORS errors: Enable CORS on API Gateway / Function App (for web).
  • Camera denied: Verify permissions and in-app prompts.
  • No provider available: Both failed; check logs and network.
  • Use Settings “Ping” buttons to test reachability quickly.
Legal Age — ID & Face Verification (Flutter) | Number Chest Apps For Sale
Legal Age App Logo ID & Face Verification

Legal Age — ID & Face Verification (Flutter)

Legal Age is a modern, agency-ready mobile app to verify legal age and confirm identity by comparing an ID photo to a live selfie. The app supports dual cloud providers (AWS + Azure) with automatic failover, keeping secrets on the server side for security and compliance.

Use Case

Legal-age gating, KYC-lite, regulated content and commerce.

Tech Stack

Flutter · Firebase (optional) · AWS Rekognition · Azure Face API

Pricing

Serious offers only – includes app, backend patterns and documentation.

Features

Everything you need for age & ID verification in one Flutter app.

📸 Capture & Match

  • ID + selfie capture via device camera.
  • Face match between ID face and live selfie.
  • Legal-age decision (18/21/custom) with clear messaging.

🤖 Cloud Intelligence

  • AWS Rekognition: CompareFaces & DetectFaces.
  • Azure Face API: verify & detect?returnFaceAttributes=age.
  • Age estimation with confidence scores.

🧠 Automatic Failover

  • Primary provider preference (AWS or Azure).
  • Automatic fallback on network/HTTP/parse errors.
  • UI shows which provider handled the final result.

🎨 Agency-Ready UI

  • Material 3, high contrast, dark mode.
  • Step-by-step flows with clear statuses.
  • Results summaries and explanatory text for edge cases.

⚙️ Runtime Settings

  • Switch primary provider at runtime.
  • Override API bases/keys and auth headers.
  • Configure legal-age threshold; persisted via SharedPreferences.

🔐 Security First

  • Server-side secrets; app only talks to your proxies.
  • Optional auditing hooks (e.g., Firestore logs).
  • Clear guidance for JWT protection and data retention.

Architecture Overview

Clean separation between Flutter app, proxy services, and cloud providers.

Mobile (Flutter)

  • main.dart — app entry, global error handling, theming.
  • id_scanner_app.dart — shell with a private navigator.
  • id_scanner_home_page.dart — home with quick actions.
  • main_screen.dart — guided overview and entry to verification.
  • face_verification_screen.dart — capture, verify, results.
  • settings_screen.dart — provider, threshold, and runtime overrides.

Backends (Server-Side)

  • AWS Lambda + API Gateway for Rekognition.
  • Azure Functions for Azure Face API.
  • Both expose normalized JSON for the Flutter app.

Data Flow

Camera (ID & Selfie) → Flutter App → Your Proxy API (AWS or Azure). On failure, the orchestrator falls back to the secondary provider and returns normalized results: { matched, confidence, estimatedAge, ageConfidence, provider }.

Getting Started

Prerequisites

  • Flutter 3.19+.
  • Xcode (iOS) and Android SDK (Android).
  • AWS and/or Azure accounts for backends.

Core Dependencies

dependencies:
  flutter:
    sdk: flutter
  http: ^1.2.2
  image_picker: ^1.1.2
  google_fonts: ^6.2.1
  shared_preferences: ^2.3.2
          

Runtime Configuration

Environment-agnostic builds using --dart-define and runtime overrides.

Dart Define Example Purpose
AWS_API_BASE https://abc.execute-api.us-east-1.amazonaws.com/prod API Gateway base URL for AWS Lambdas.
AZURE_FN_BASE https://your-fn.azurewebsites.net Azure Function App base URL.
AZURE_FN_CODE ... (optional) Function key if required by your auth level.
AUTH_BEARER eyJhbGciOiJI... JWT/ID token header for your gateways (optional).
PRIMARY_PROVIDER aws or azure Default provider preference.

All of these can be overridden at runtime via the Settings screen and persisted using SharedPreferences.

Platform Permissions

iOS — Info.plist

<key>NSCameraUsageDescription</key>
<string>Camera is used to capture ID photos and selfies for verification.</string>
<key>NSPhotoLibraryUsageDescription</key>
<string>Photo library access is used to pick images for verification.</string>
          

Deploying the Backends

AWS + Azure patterns ready for your infrastructure team.

AWS: Rekognition + Lambda + API Gateway

IAM Role policy (Lambda):

{
  "Version": "2012-10-17",
  "Statement": [
    {"Effect":"Allow","Action":["rekognition:CompareFaces","rekognition:DetectFaces"],"Resource":"*"},
    {"Effect":"Allow","Action":["s3:GetObject"],"Resource":"*"}
  ]
}
            
  • Create two Node.js 20 Lambdas: POST /compare, POST /detect.
  • Wire them via an HTTP API in API Gateway with CORS enabled.
  • Use multipart form-data: idImage, selfieImage, or image.

Sample tests:

curl -X POST "$AWS_API_BASE/compare" \
  -F idImage=@id.jpg -F selfieImage=@selfie.jpg

curl -X POST "$AWS_API_BASE/detect" \
  -F image=@selfie.jpg
            

Build & Run

Development

flutter pub get

flutter run \
  --dart-define=AWS_API_BASE=https://abc.execute-api.us-east-1.amazonaws.com/prod \
  --dart-define=AZURE_FN_BASE=https://your-fn.azurewebsites.net \
  --dart-define=PRIMARY_PROVIDER=aws
          

Android Release

flutter build apk --release \
  --dart-define=AWS_API_BASE=... \
  --dart-define=AZURE_FN_BASE=... \
  --dart-define=PRIMARY_PROVIDER=aws
# or:
# flutter build appbundle --release ...
          

iOS Release

flutter build ios --release \
  --dart-define=AWS_API_BASE=... \
  --dart-define=AZURE_FN_BASE=... \
  --dart-define=PRIMARY_PROVIDER=azure
# Then archive/sign in Xcode as usual
          

Testing & QA

Happy Path

  • Clear ID and selfie of the same person → matched=true, high confidence.
  • Plausible age from selfie with confidence metrics.

Fallback Scenarios

  • Temporarily disable one backend → expect successful result via the other.
  • UI clearly indicates “Fallback used”.

Edge Cases

  • No face detected → matched=false, estimatedAge=null.
  • Multiple faces → first face used; prompt user to retake.
  • Poor lighting / occlusions → lower confidence but safe messaging.

Troubleshooting

  • AWS_API_BASE / AZURE_FN_BASE empty: Set via --dart-define or Settings.
  • 403/401: Check AZURE_FN_CODE or JWT auth.
  • CORS errors: Enable CORS on API Gateway / Function App (for web).
  • Camera denied: Verify permissions and in-app prompts.
  • No provider available: Both failed; check logs and network.
  • Use Settings “Ping” buttons to test reachability quickly.