{"id":16417328,"url":"https://github.com/mkalioby/django-passkeys","last_synced_at":"2026-04-12T16:35:35.235Z","repository":{"id":62204610,"uuid":"558787909","full_name":"mkalioby/django-passkeys","owner":"mkalioby","description":"Django Authentication Backend For Passkeys","archived":false,"fork":false,"pushed_at":"2025-04-02T15:12:32.000Z","size":5072,"stargazers_count":217,"open_issues_count":21,"forks_count":24,"subscribers_count":10,"default_branch":"main","last_synced_at":"2025-05-13T04:40:32.555Z","etag":null,"topics":["biometrics","django","passkeys","python","security","security-key","webauthn"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mkalioby.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2022-10-28T09:46:58.000Z","updated_at":"2025-05-08T17:58:59.000Z","dependencies_parsed_at":"2023-11-09T11:58:27.324Z","dependency_job_id":"6c74a2de-5dcf-412c-a547-16bea0f6d1c5","html_url":"https://github.com/mkalioby/django-passkeys","commit_stats":{"total_commits":17,"total_committers":2,"mean_commits":8.5,"dds":0.05882352941176472,"last_synced_commit":"5aeeb67273a73e4b892b14c98bed7a136f4bc3a5"},"previous_names":[],"tags_count":5,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mkalioby%2Fdjango-passkeys","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mkalioby%2Fdjango-passkeys/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mkalioby%2Fdjango-passkeys/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mkalioby%2Fdjango-passkeys/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mkalioby","download_url":"https://codeload.github.com/mkalioby/django-passkeys/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253878833,"owners_count":21977882,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["biometrics","django","passkeys","python","security","security-key","webauthn"],"created_at":"2024-10-11T07:11:26.683Z","updated_at":"2026-04-12T16:35:35.228Z","avatar_url":"https://github.com/mkalioby.png","language":"Python","readme":"# django-passkeys\n\n[![PyPI version](https://badge.fury.io/py/django-passkeys.svg)](https://badge.fury.io/py/django-passkeys)\n[![Downloads](https://static.pepy.tech/badge/django-passkeys)](https://pepy.tech/project/django-passkeys)\n[![Downloads / Month ](https://pepy.tech/badge/django-passkeys/month)](https://pepy.tech/project/django-passkeys)\n[![build](https://github.com/mkalioby/django-passkeys/actions/workflows/basic_checks.yml/badge.svg)](https://github.com/mkalioby/django-passkeys/actions/workflows/basic_checks.yml)\n![Coverage](https://raw.githubusercontent.com/mkalioby/django-passkeys/main/coverage.svg)\n[![docs](https://app.readthedocs.org/projects/django-passkeys/badge/?version=v2.0)](https://django-passkeys.readthedocs.io/en/latest/)\n\n![Django Versions](https://img.shields.io/pypi/frameworkversions/django/django-passkeys)\n![Python Versions](https://img.shields.io/pypi/pyversions/django-passkeys)\n\n\nAn extension to Django *ModelBackend* backend to support passkeys. Supports both django templates and REST API (Django REST Framework) with pluggable token backends (JWT, DRF Token, or Session).\n\nPasskeys is an extension to Web Authentication API that will allow the user to login to a service using another device.\n\nThis app is a slimmed-down version of [django-mfa2](https://github.com/mkalioby/django-mfa2)\n\nPasskeys are now supported on\n* Apple Ecosystem (iPhone 16.0+, iPadOS 16.1, Mac OS X Ventura)\n* Chromium based browsers (on PC and Laptop) allows picking up credentials from Android and iPhone/iPadOS.\n* Android Credentials creation for ResidentKeys is currently live.\n\nOn May 3, 2023, Google allowed the use of Passkeys for the users to login, killing the password for enrolled users.\n\n## Special Features\n\ndjango-passkeys supports the following features:\n### 1. Conditional UI\n**Conditional UI** is a way for the browser to prompt the user to use the passkey to login as shown.\n![conditionalUI.png](docs/imgs%2FconditionalUI.png)\n\n### 2. WebAuthn immediate mediation for frictionless sign-in\n\n**Immediate Mediation** is an extension to WebAuthn API that allows the browser to immediately prompt the\nuser to use password/passkeys without the need of a login form. This is currently supported by Google Chrome 144+ and soon on Android devices.\n\nYou can watch demo presented by Google\n\n[![Watch the video](docs/imgs/immediate.png)](https://developer.chrome.com//static/blog/webauthn-immediate-mediation-ot/video/immediate-mediation-explicit-flow.mp4)\n\n# Quick Start - Common Settings\n\n`pip install django-passkeys`\n\nSupports Django 2.2+, Python 3.7+\n\n# Usage\n1. In your settings.py add the application to your installed apps\n   ```python\n   INSTALLED_APPS=(\n   '......',\n   'passkeys',\n   '......')\n   ```\n2. Collect Static Files\n   ```shell\n   python manage.py collectstatic\n   ```\n\n3. Run migrate\n   ```shell\n    python manage.py migrate\n   ```\n4. Add the following settings to your file\n\n   ```python\n    AUTHENTICATION_BACKENDS = ['passkeys.backend.PasskeyModelBackend'] # Change your authentication backend\n    FIDO_SERVER_ID=\"localhost\"      # Server rp id for FIDO2, must match your domain\n    FIDO_SERVER_NAME=\"TestApp\"\n    import passkeys\n    KEY_ATTACHMENT = None # or passkeys.Attachment.CROSS_PLATFORM or  passkeys.Attachment.PLATFORM\n   ```\n   **Notes**\n    \n   * Starting v1.1, `FIDO_SERVER_ID` and/or `FIDO_SERVER_NAME` can be a callable to support multi-tenant web applications, the `request` is passed to the called function. \n   * `FIDO_SERVER_ID` must match the domain you access the site from. For local development, use `localhost` and access via `http://localhost:8000/` (not `127.0.0.1`).\n\n# Detect if user is using passkeys\nOnce the backend is used, there will be a `passkey` key in request.session. \nIf the user used a passkey then `request.session['passkey']['passkey']` will be `True` and the key information will be there like this\n\n```python\n{'passkey': True, 'name': 'Chrome', 'id': 2, 'platform': 'Chrome on Apple', 'cross_platform': False}\n```\n`cross_platform`: means that the user used a key from another platform so there is no key local to the device used to login e.g used an Android phone on Mac OS X or iPad.\nIf the user didn't use a passkey then it will be set to False\n```python\n{'passkey':False}\n```\n\nBy this the basic installation of django-passkeys, your next step depends on whether you want to use the Django Template integration or the REST API (Django REST Framework) integration.\n\n## Choose Your Integration\n\ndjango-passkeys supports two integration modes. Pick the one that fits your project:\n\n| | Template-Based | REST API (DRF) |\n|---|---|---|\n| **Best for** | Server-rendered Django apps | SPAs, mobile apps, headless APIs |\n| **Auth flow** | Session-based with Django forms | Token-based (JWT, DRF Token, or Session) |\n| **Frontend** | Django templates with jQuery | Any frontend (React, Vue, mobile, etc.) |\n| **Setup guide** | [Template Setup](docs/template-setup.md) | [DRF Setup](docs/drf-setup.md) |\n\n\nBoth can coexist in the same project — you can use templates for your web app and the API for your mobile app.\n\n## Example Project\n\nSee the `example` app and [Example.md](docs/Example.md) for a working demo for templates, drf and immediate mediation.\n\n## Security contact information\n\nTo report a security vulnerability, please use the\n[Tidelift security contact](https://tidelift.com/security).\nTidelift will coordinate the fix and disclosure.\n\n## Contributors\n* [mahmoodnasr](https://github.com/mahmoodnasr)\n* [jacopsd](https://github.com/jacopsd)\n* [gasparbrogueira](https://github.com/gasparbrogueira)\n* [pulse-mind](https://github.com/pulse-mind)\n* [ashokdelphia](https://github.com/ashokdelphia)\n* [offbyone](https://github.com/offbyone)\n* [resba](https://github.com/resba)\n* [ganiyevuz](https://github.com/ganiyevuz)\n* [smark-1](https://github.com/smark-1)\n* [ThomasWaldmann-1](https://github.com/ThomasWaldmann)\n* [rafaelurben](https://github.com/rafaelurben)\n","funding_links":["https://tidelift.com/security"],"categories":["Python"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmkalioby%2Fdjango-passkeys","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmkalioby%2Fdjango-passkeys","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmkalioby%2Fdjango-passkeys/lists"}