goauthentik / goauthentik/authentik
scim provider: allow syncing only users or only groups
- Dominant language
- Python
- Stars
- 25.6k
- Forks
- 2k
- Avg merge
- 1d 2h
- Merged PRs (30d)
- 651
Description
**Describe the bug**
I've set up SCIM for GitHub Organization. When I look at the SCIM provider I see a long Exception error. However, when I query the API or look in the GitHub console, SCIM has worked correctly!
**To Reproduce**
Steps to reproduce the behavior:
1. Setup GitHub Organization SAML as documented at https://docs.goauthentik.io/integrations/services/github-organization/
2. Create a fine-grained token with Write access to Organization Members
3. Setup a SCIM provider with URLs as documented by GitHub https://docs.github.com/en/enterprise-cloud@latest/rest/scim/scim?apiVersion=2022-11-28#scim-provisioning-for-organizations
4. Run a sync
5. View SCIM mappings for each user by querying https://api.github.com/scim/v2/organizations/ORGNAME/Users confirms that the users are synced
6. View invitations for users provisioned in Authentik but not active in GitHub in the console or https://api.github.com/scim/v2/organizations/ORGNAME/invitations
...
7. Be utterly confused why Authentik logs only a NotFound exception in Sync Status
**Logs**
Expand to see JSON logs...
```
{"domain_url": null, "event": "Task started", "level": "info", "logger": "authentik.root.celery", "pid": 5521, "schema_name": "public", "task_id": "9c78603a-f0bb-4a99-a90b-6b75962ce2b1", "task_name": "scim_sync_objects", "timestamp": "2025-03-08T18:34:27.202935"}
{"domain_url": null, "event": "failed to get ServiceProviderConfig", "exc": "NotFoundSyncException()", "level": "warning", "logger": "authentik.lib.sync.outgoing.base", "pid": 5521, "provider": "GitHub SCIM", "schema_name": "public", "task_id": "task-9c78603af0bb4a99a90b6b75962ce2b1", "timestamp": "2025-03-08T18:34:27.417693"}
{"domain_url": null, "event": "Task finished", "level": "info", "logger": "authentik.root.celery", "pid": 5521, "schema_name": "public", "state": "SUCCESS", "task_id": "9c78603af0bb4a99a90b6b75962ce2b1", "task_name": "scim_sync_objects", "timestamp": "2025-03-08T18:34:31.940549"}
{"domain_url": null, "event": "Task published", "level": "info", "logger": "authentik.root.celery", "pid": 5523, "schema_name": "public", "task_id": "9b93b6344f974311bcab66c1ae7f7e6c", "task_name": "authentik.providers.scim.tasks.scim_sync_objects", "timestamp": "2025-03-08T18:34:31.950457"}
{"domain_url": null, "event": "Task started", "level": "info", "logger": "authentik.root.celery", "pid": 5521, "schema_name": "public", "task_id": "9b93b634-4f97-4311-bcab-66c1ae7f7e6c", "task_name": "scim_sync_objects", "timestamp": "2025-03-08T18:34:31.954312"}
{"domain_url": null, "event": "failed to get ServiceProviderConfig", "exc": "NotFoundSyncException()", "level": "warning", "logger": "authentik.lib.sync.outgoing.base", "pid": 5521, "provider": "GitHub SCIM", "schema_name": "public", "task_id": "task-9b93b6344f974311bcab66c1ae7f7e6c", "timestamp": "2025-03-08T18:34:32.123067"}
{"event": "Task authentik.providers.scim.tasks.scim_sync_objects[9b93b634-4f97-4311-bcab-66c1ae7f7e6c] raised unexpected: NotFoundSyncException()", "exception": [{"exc_type": "NotFoundSyncException", "exc_value": "", "frames": [{"filename": "/ak-root/venv/lib/python3.12/site-packages/celery/app/trace.py", "lineno": 453, "locals": {"I": "None", "IGNORE_STATES": "frozenset({'REJECTED', 'RETRY', 'IGNORED'})", "Info": "", "R": "None", "Rstr": "None", "T": "None", "_does_info": "False", "app": "", "args": "['authentik.core.models.Group', 1, 12]", "deduplicate_successful_tasks": "False", "eager": "False", "exc": "NotFoundSyncException()", "fun": "'<@task: authentik.providers.scim.tasks.scim_sync_objects of authentik at 0x7f656'+8", "hostname": "'celery@de9193d23122'", "inherit_parent_priority": "False", "kwargs": "{}", "loader_cleanup": "'", "name": "'authentik.providers.scim.tasks.scim_sync_objects'", "on_error": ".on_error at 0x7f655f9a4540>", "pid": "5521", "pop_request": "'", "state": "None", "success_receivers": "[]", "task": "'<@task: authentik.providers.scim.tasks.scim_sync_objects of authentik at 0x7f656'+8", "task_after_return": "None", "task_before_start": "None", "task_on_success": "None", "task_priority": "None", "task_request": "\"", "track_started": "False", "uuid": "'9b93b634-4f97-4311-bcab-66c1ae7f7e6c'"}, "name": "trace_task"}, {"filename": "/ak-root/venv/lib/python3.12/site-packages/sentry_sdk/utils.py", "lineno": 1783, "locals": {"args": "'(<@task: authentik.providers.scim.tasks.scim_sync_objects of authentik at 0x7f65'+48", "integration": "", "kwargs": "{}", "original_function": "'.__protected_call__ at 0x7f656e6ded4'+2", "sentry_patched_function": "._inner at 0x7f6560c032e0>"}, "name": "runner"}, {"filename": "/ak-root/venv/lib/python3.12/site-packages/sentry_sdk/integrations/celery/__init__.py", "lineno": 415, "locals": {"args": "'(<@task: authentik.providers.scim.tasks.scim_sync_objects of authentik at 0x7f65'+48", "exc_info": "\"(, NotFoun\"+71", "f": "'.__protected_call__ at 0x7f656e6ded4'+2", "kwargs": "{}", "latency": "0.010670185089111328", "span": "\"", "tp": "", "value": "NotFoundSyncException()"}, "name": "reraise"}, {"filename": "/ak-root/venv/lib/python3.12/site-packages/sentry_sdk/integrations/celery/__init__.py", "lineno": 410, "locals": {"args": "'(<@task: authentik.providers.scim.tasks.scim_sync_objects of authentik at 0x7f65'+48", "exc_info": "\"(, NotFoun\"+71", "f": "'.__protected_call__ at 0x7f656e6ded4'+2", "kwargs": "{}", "latency": "0.010670185089111328", "span": "\"", "req": "\""}, "name": "__protected_call__"}, {"filename": "/ak-root/venv/lib/python3.12/site-packages/celery/app/autoretry.py", "lineno": 38, "locals": {"args": "('authentik.core.models.Group', 1, 12)", "autoretry_for": "(,)", "dont_autoretry_for": "()", "kwargs": "{}", "retry_backoff": "1.0", "retry_backoff_max": "600", "retry_jitter": "True", "retry_kwargs": "{}", "task": "'<@task: authentik.providers.scim.tasks.scim_sync_objects of authentik at 0x7f656'+8"}, "name": "run"}, {"filename": "/authentik/providers/scim/tasks.py", "lineno": 14, "locals": {"args": "('authentik.core.models.Group', 1, 12)", "kwargs": "{}"}, "name": "scim_sync_objects"}, {"filename": "/authentik/lib/sync/outgoing/tasks.py", "lineno": 131, "locals": {"_object_type": "", "client": "'", "object_type": "'authentik.core.models.Group'", "page": "1", "paginator": "", "provider": "", "provider_pk": "12", "self": ""}, "name": "sync_objects"}, {"filename": "/authentik/lib/sync/outgoing/base.py", "lineno": 63, "locals": {"connection": "None", "obj": "", "self": "'", "scim_group": "\"Group(id=None, displayName='devx', members=[GroupMember(value='ed5d1222-fc47-11e\"+156", "self": "'", "self": "'"}, "domain_url": null, "event": "Created Event", "level": "info", "logger": "authentik.events.models", "pid": 5523, "schema_name": "public", "task_id": "task-6b6bba6efedd4c9b80ab666e120ca32f", "timestamp": "2025-03-08T18:34:33.796304", "user": {}}
{"event": "Task authentik.providers.scim.tasks.scim_sync[6b6bba6e-fedd-4c9b-80ab-666e120ca32f] raised unexpected: NotFoundSyncException('')", "exception": [{"exc_type": "NotFoundSyncException", "exc_value": "", "frames": [{"filename": "/ak-root/venv/lib/python3.12/site-packages/celery/app/trace.py", "lineno": 453, "locals": {"I": "None", "IGNORE_STATES": "frozenset({'REJECTED', 'RETRY', 'IGNORED'})", "Info": "", "R": "None", "Rstr": "None", "T": "None", "_does_info": "False", "app": "", "args": "[12]", "deduplicate_successful_tasks": "False", "eager": "False", "exc": "NotFoundSyncException('')", "fun": "<@task: authentik.providers.scim.tasks.scim_sync of authentik at 0x7f6569915c70>", "hostname": "'celery@de9193d23122'", "inherit_parent_priority": "False", "kwargs": "{}", "loader_cleanup": "'", "name": "'authentik.providers.scim.tasks.scim_sync'", "on_error": ".on_error at 0x7f6560c036a0>", "pid": "5523", "pop_request": "'", "state": "None", "success_receivers": "[]", "task": "<@task: authentik.providers.scim.tasks.scim_sync of authentik at 0x7f6569915c70>", "task_after_return": "'", "track_started": "False", "uuid": "'6b6bba6e-fedd-4c9b-80ab-666e120ca32f'"}, "name": "trace_task"}, {"filename": "/ak-root/venv/lib/python3.12/site-packages/sentry_sdk/utils.py", "lineno": 1783, "locals": {"args": "'(<@task: authentik.providers.scim.tasks.scim_sync of authentik at 0x7f6569915c70'+6", "integration": "", "kwargs": "{}", "original_function": "'.__protected_call__ at 0x7f656e6ded4'+2", "sentry_patched_function": "._inner at 0x7f6560c03920>"}, "name": "runner"}, {"filename": "/ak-root/venv/lib/python3.12/site-packages/sentry_sdk/integrations/celery/__init__.py", "lineno": 415, "locals": {"args": "'(<@task: authentik.providers.scim.tasks.scim_sync of authentik at 0x7f6569915c70'+6", "exc_info": "\"(, NotFoun\"+73", "f": "'.__protected_call__ at 0x7f656e6ded4'+2", "kwargs": "{}", "latency": "0.026908159255981445", "span": "\""}, "name": "_inner"}, {"filename": "/ak-root/venv/lib/python3.12/site-packages/sentry_sdk/utils.py", "lineno": 1718, "locals": {"tb": "", "tp": "", "value": "NotFoundSyncException('')"}, "name": "reraise"}, {"filename": "/ak-root/venv/lib/python3.12/site-packages/sentry_sdk/integrations/celery/__init__.py", "lineno": 410, "locals": {"args": "'(<@task: authentik.providers.scim.tasks.scim_sync of authentik at 0x7f6569915c70'+6", "exc_info": "\"(, NotFoun\"+73", "f": "'.__protected_call__ at 0x7f656e6ded4'+2", "kwargs": "{}", "latency": "0.026908159255981445", "span": "\""}, "name": "_inner"}, {"filename": "/ak-root/venv/lib/python3.12/site-packages/celery/app/trace.py", "lineno": 736, "locals": {"args": "(12,)", "kwargs": "{}", "orig": "", "req": "\"", "stack": ""}, "name": "__protected_call__"}, {"filename": "/ak-root/venv/lib/python3.12/site-packages/celery/app/autoretry.py", "lineno": 38, "locals": {"args": "(12,)", "autoretry_for": "(,)", "dont_autoretry_for": "()", "kwargs": "{}", "retry_backoff": "1.0", "retry_backoff_max": "600", "retry_jitter": "True", "retry_kwargs": "{}", "task": "<@task: authentik.providers.scim.tasks.scim_sync of authentik at 0x7f6569915c70>"}, "name": "run"}, {"filename": "/authentik/providers/scim/tasks.py", "lineno": 22, "locals": {"args": "()", "kwargs": "{}", "provider_pk": "12", "self": "<@task: authentik.providers.scim.tasks.scim_sync of authentik at 0x7f6569915c70>"}, "name": "scim_sync"}, {"filename": "/authentik/lib/sync/outgoing/tasks.py", "lineno": 98, "locals": {"groups_paginator": "", "lock_acquired": "True", "messages": "\"['Starting full provider sync', 'Syncing page 1 of users', 'Syncing page 1 of gr\"+6", "page": "1", "provider": "", "provider_pk": "12", "self": "", "sync_objects": "'<@task: authentik.providers.scim.tasks.scim_sync_objects of authentik at 0x7f656'+8", "task": "<@task: authentik.providers.scim.tasks.scim_sync of authentik at 0x7f6569915c70>", "users_paginator": ""}, "name": "sync_single"}, {"filename": "/ak-root/venv/lib/python3.12/site-packages/celery/result.py", "lineno": 251, "locals": {"EXCEPTION_STATES": "frozenset({'FAILURE', 'RETRY', 'REVOKED'})", "PROPAGATE_STATES": "frozenset({'FAILURE', 'REVOKED'})", "_on_interval": "", "callback": "None", "disable_sync_subtasks": "True", "follow_parents": "True", "interval": "0.5", "no_ack": "True", "on_interval": "None", "on_message": "None", "propagate": "True", "self": "", "timeout": "None"}, "name": "get"}, {"filename": "/ak-root/venv/lib/python3.12/site-packages/celery/backends/asynchronous.py", "lineno": 223, "locals": {"_": "None", "callback": "None", "kwargs": "\"{'timeout': None, 'interval': 0.5, 'on_interval': , 'no_\"+31", "propagate": "True", "result": "", "self": ""}, "name": "wait_for_pending"}, {"filename": "/ak-root/venv/lib/python3.12/site-packages/celery/result.py", "l
{"domain_url": null, "event": "Task finished", "level": "info", "logger": "authentik.root.celery", "pid": 5523, "schema_name": "public", "state": "FAILURE", "task_id": "6b6bba6efedd4c9b80ab666e120ca32f", "task_name": "scim_sync", "timestamp": "2025-03-08T18:34:33.825222"}
```
**Version and Deployment (please complete the following information):**
- authentik version: [e.g. 2025.2.0] 2025.2.1
- Deployment: [e.g. docker-compose, helm] podman quadlets (podman run by systemd)
**Additional context**
Add any other context about the problem here.
GitHub apparently doesn't provide the `/ServiceProviderConfig` which results in 404, is this perhaps being raised up as the sole error? Or is something else in the operation failing?
Contributor guide
Research direction
Start with authentik/providers/scim/tasks.py and the sync flow in authentik/lib/sync/outgoing/tasks.py, then inspect the clients in authentik/providers/scim/clients/groups.py and base.py. Check how the GitHub SCIM URLs handle missing user or group endpoints; done means a provider can select only users or only groups and syncing the selected resource type completes without an unrelated 404 failure.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- github, python
- Domain
- api, backend
- Issue type
- Feature
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100