Pyattest
Pyattest is a Python library that provides a common interface for verifying mobile app attestations from both Google and Apple. It offers a standalone solution, but for full Django integration, including key generation and storage, the companion `django-dreiattest` package is recommended. The library is currently at version 1.0.4 and has an infrequent release cadence, with updates typically including security fixes and dependency updates.
Warnings
- gotcha For full integration with Django, including key generation and storage, users should install and configure the separate `django-dreiattest` library. `pyattest` provides the core attestation verification logic but does not handle Django-specific features like database models or admin integration directly.
- gotcha When configuring the Google Play Integrity API, the `allow_non_play_distribution` parameter should generally be `False` for production builds to ensure app integrity. If set to `True`, `verify_code_signature_hex` becomes mandatory and must be the SHA-256 hash of your app's signing identity. Avoid using `allow_non_play_distribution=True` for development builds; instead, set `production=False`.
- gotcha It is crucial to call the `attestation.verify()` method and check its return value (or catch exceptions) *before* attempting to access any parsed data or assertion details from the `Attestation` object. Accessing data before successful verification can lead to errors or incorrect assumptions about the attestation's validity.
Install
-
pip install pyattest
Imports
- GoogleConfig
from pyattest import GoogleConfig
- GooglePlayIntegrityApiConfig
from pyattest import GooglePlayIntegrityApiConfig
- AppleConfig
from pyattest import AppleConfig
- Attestation
from pyattest import Attestation
- Assertion
from pyattest.assertion import Assertion
Quickstart
import os
from pyattest import GooglePlayIntegrityApiConfig, Attestation
# These would typically come from secure environment variables or a key management system
decryption_key = os.environ.get('PYATTEST_DECRYPTION_KEY', 'YOUR_BASE64_DECRYPTION_KEY')
verification_key = os.environ.get('PYATTEST_VERIFICATION_KEY', 'YOUR_BASE64_VERIFICATION_KEY')
# Mock data for demonstration purposes
mock_attest_jwt = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c'
mock_nonce = 'sample-nonce-123'
mock_apk_package_name = 'ch.dreipol.demo'
try:
config = GooglePlayIntegrityApiConfig(
decryption_key=decryption_key,
verification_key=verification_key,
apk_package_name=mock_apk_package_name,
production=True,
allow_non_play_distribution=False,
# verify_code_signature_hex must be provided if allow_non_play_distribution is True
# required_device_verdict="MEETS_STRONG_INTEGRITY"
)
attestation = Attestation(
attest=mock_attest_jwt,
nonce=mock_nonce,
config=config
)
is_valid = attestation.verify() # This performs the actual verification
print(f"Attestation is valid: {is_valid}")
if is_valid:
# Once verified, you can access properties like device integrity, account details, etc.
# Example: print(attestation.parsed_data.deviceIntegrity.deviceRecognition.deviceVerdict)
print("Attestation successfully verified.")
else:
print("Attestation verification failed.")
except Exception as e:
print(f"An error occurred during attestation verification: {e}")