src-auth-perms-sync 0.6.0__tar.gz → 0.7.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {src_auth_perms_sync-0.6.0 → src_auth_perms_sync-0.7.0}/.github/workflows/validate.yml +7 -2
- {src_auth_perms_sync-0.6.0 → src_auth_perms_sync-0.7.0}/.gitignore +2 -5
- src_auth_perms_sync-0.7.0/.markdownlint-cli2.yaml +15 -0
- {src_auth_perms_sync-0.6.0 → src_auth_perms_sync-0.7.0}/AGENTS.md +12 -3
- {src_auth_perms_sync-0.6.0 → src_auth_perms_sync-0.7.0}/PKG-INFO +40 -6
- {src_auth_perms_sync-0.6.0 → src_auth_perms_sync-0.7.0}/README.md +39 -5
- {src_auth_perms_sync-0.6.0 → src_auth_perms_sync-0.7.0}/dev/TODO.md +1 -1
- {src_auth_perms_sync-0.6.0 → src_auth_perms_sync-0.7.0}/dev/engineering-requests.md +9 -9
- {src_auth_perms_sync-0.6.0 → src_auth_perms_sync-0.7.0}/dev/memory-analysis/mapping-efficiency.md +2 -2
- {src_auth_perms_sync-0.6.0 → src_auth_perms_sync-0.7.0}/dev/memory-analysis/memory-efficiency.md +3 -3
- src_auth_perms_sync-0.7.0/examples/import.py +63 -0
- src_auth_perms_sync-0.7.0/package-lock.json +1377 -0
- src_auth_perms_sync-0.7.0/package.json +11 -0
- {src_auth_perms_sync-0.6.0 → src_auth_perms_sync-0.7.0}/pyproject.toml +4 -1
- {src_auth_perms_sync-0.6.0 → src_auth_perms_sync-0.7.0}/src/src_auth_perms_sync/cli.py +91 -25
- {src_auth_perms_sync-0.6.0 → src_auth_perms_sync-0.7.0}/src/src_auth_perms_sync/orgs/command.py +2 -2
- src_auth_perms_sync-0.7.0/src/src_auth_perms_sync/orgs/queries.py +90 -0
- {src_auth_perms_sync-0.6.0 → src_auth_perms_sync-0.7.0}/src/src_auth_perms_sync/orgs/sync.py +502 -97
- {src_auth_perms_sync-0.6.0 → src_auth_perms_sync-0.7.0}/src/src_auth_perms_sync/orgs/types.py +6 -0
- {src_auth_perms_sync-0.6.0 → src_auth_perms_sync-0.7.0}/src/src_auth_perms_sync/permissions/command.py +86 -25
- {src_auth_perms_sync-0.6.0 → src_auth_perms_sync-0.7.0}/src/src_auth_perms_sync/permissions/mapping.py +1 -1
- {src_auth_perms_sync-0.6.0 → src_auth_perms_sync-0.7.0}/src/src_auth_perms_sync/permissions/queries.py +39 -5
- {src_auth_perms_sync-0.6.0 → src_auth_perms_sync-0.7.0}/src/src_auth_perms_sync/permissions/sourcegraph.py +6 -0
- {src_auth_perms_sync-0.6.0 → src_auth_perms_sync-0.7.0}/src/src_auth_perms_sync/shared/queries.py +10 -1
- {src_auth_perms_sync-0.6.0 → src_auth_perms_sync-0.7.0}/src/src_auth_perms_sync/shared/run_context.py +8 -0
- {src_auth_perms_sync-0.6.0 → src_auth_perms_sync-0.7.0}/src/src_auth_perms_sync/shared/saml_groups.py +92 -4
- {src_auth_perms_sync-0.6.0 → src_auth_perms_sync-0.7.0}/src/src_auth_perms_sync/shared/sourcegraph.py +4 -0
- {src_auth_perms_sync-0.6.0 → src_auth_perms_sync-0.7.0}/src/src_auth_perms_sync/shared/types.py +24 -0
- src_auth_perms_sync-0.7.0/tests/confusables.py +215 -0
- {src_auth_perms_sync-0.6.0 → src_auth_perms_sync-0.7.0}/tests/e2e/case_runner.py +179 -2
- src_auth_perms_sync-0.7.0/tests/e2e/fixtures/set-users-sync-saml-orgs-noop/before.json +108 -0
- src_auth_perms_sync-0.7.0/tests/e2e/fixtures/set-users-sync-saml-orgs-noop/maps.yaml +8 -0
- src_auth_perms_sync-0.7.0/tests/e2e/fixtures/set-users-sync-saml-orgs-scoped/after.json +109 -0
- src_auth_perms_sync-0.7.0/tests/e2e/fixtures/set-users-sync-saml-orgs-scoped/before.json +104 -0
- src_auth_perms_sync-0.7.0/tests/e2e/fixtures/set-users-sync-saml-orgs-scoped/maps.yaml +8 -0
- src_auth_perms_sync-0.7.0/tests/e2e/fixtures/sync-saml-orgs-full-cleanup/after.json +111 -0
- src_auth_perms_sync-0.7.0/tests/e2e/fixtures/sync-saml-orgs-full-cleanup/before.json +106 -0
- src_auth_perms_sync-0.7.0/tests/e2e/fixtures/sync-saml-orgs-users-scoped/after.json +113 -0
- src_auth_perms_sync-0.7.0/tests/e2e/fixtures/sync-saml-orgs-users-scoped/before.json +107 -0
- {src_auth_perms_sync-0.6.0 → src_auth_perms_sync-0.7.0}/tests/run.py +5 -1
- {src_auth_perms_sync-0.6.0 → src_auth_perms_sync-0.7.0}/tests/tests.yaml +916 -27
- {src_auth_perms_sync-0.6.0 → src_auth_perms_sync-0.7.0}/tests/unit/test_cli_config.py +58 -13
- {src_auth_perms_sync-0.6.0 → src_auth_perms_sync-0.7.0}/tests/unit/test_command_files.py +1 -1
- src_auth_perms_sync-0.7.0/tests/unit/test_confusables.py +35 -0
- {src_auth_perms_sync-0.6.0 → src_auth_perms_sync-0.7.0}/tests/unit/test_saml_groups.py +86 -0
- src_auth_perms_sync-0.6.0/.env.example +0 -36
- src_auth_perms_sync-0.6.0/.markdownlint-cli2.yaml +0 -9
- src_auth_perms_sync-0.6.0/dev/PLAN.md +0 -458
- src_auth_perms_sync-0.6.0/src/src_auth_perms_sync/orgs/queries.py +0 -44
- {src_auth_perms_sync-0.6.0 → src_auth_perms_sync-0.7.0}/.github/CODEOWNERS +0 -0
- {src_auth_perms_sync-0.6.0 → src_auth_perms_sync-0.7.0}/.github/workflows/ci.yml +0 -0
- {src_auth_perms_sync-0.6.0 → src_auth_perms_sync-0.7.0}/.github/workflows/release.yml +0 -0
- {src_auth_perms_sync-0.6.0 → src_auth_perms_sync-0.7.0}/.python-version +0 -0
- {src_auth_perms_sync-0.6.0 → src_auth_perms_sync-0.7.0}/LICENSE +0 -0
- {src_auth_perms_sync-0.6.0 → src_auth_perms_sync-0.7.0}/SECURITY.md +0 -0
- {src_auth_perms_sync-0.6.0 → src_auth_perms_sync-0.7.0}/dev/audit-dead-code.md +0 -0
- {src_auth_perms_sync-0.6.0 → src_auth_perms_sync-0.7.0}/dev/hooks/pre-commit +0 -0
- {src_auth_perms_sync-0.6.0 → src_auth_perms_sync-0.7.0}/dev/memory-analysis/memory-efficiency-analyze.py +0 -0
- {src_auth_perms_sync-0.6.0 → src_auth_perms_sync-0.7.0}/dev/memory-analysis/memory-efficiency-generate.py +0 -0
- {src_auth_perms_sync-0.6.0 → src_auth_perms_sync-0.7.0}/dev/memory-analysis/memory-efficiency-monitor-sourcegraph.sh +0 -0
- {src_auth_perms_sync-0.6.0 → src_auth_perms_sync-0.7.0}/dev/update-python-versions.md +0 -0
- /src_auth_perms_sync-0.6.0/maps-example.yaml → /src_auth_perms_sync-0.7.0/examples/maps.yaml +0 -0
- {src_auth_perms_sync-0.6.0 → src_auth_perms_sync-0.7.0}/renovate.json +0 -0
- {src_auth_perms_sync-0.6.0 → src_auth_perms_sync-0.7.0}/src/src_auth_perms_sync/__init__.py +0 -0
- {src_auth_perms_sync-0.6.0 → src_auth_perms_sync-0.7.0}/src/src_auth_perms_sync/__main__.py +0 -0
- {src_auth_perms_sync-0.6.0 → src_auth_perms_sync-0.7.0}/src/src_auth_perms_sync/orgs/__init__.py +0 -0
- {src_auth_perms_sync-0.6.0 → src_auth_perms_sync-0.7.0}/src/src_auth_perms_sync/permissions/__init__.py +0 -0
- {src_auth_perms_sync-0.6.0 → src_auth_perms_sync-0.7.0}/src/src_auth_perms_sync/permissions/apply.py +0 -0
- {src_auth_perms_sync-0.6.0 → src_auth_perms_sync-0.7.0}/src/src_auth_perms_sync/permissions/full_set.py +0 -0
- {src_auth_perms_sync-0.6.0 → src_auth_perms_sync-0.7.0}/src/src_auth_perms_sync/permissions/maps.py +0 -0
- {src_auth_perms_sync-0.6.0 → src_auth_perms_sync-0.7.0}/src/src_auth_perms_sync/permissions/restore.py +0 -0
- {src_auth_perms_sync-0.6.0 → src_auth_perms_sync-0.7.0}/src/src_auth_perms_sync/permissions/snapshot.py +0 -0
- {src_auth_perms_sync-0.6.0 → src_auth_perms_sync-0.7.0}/src/src_auth_perms_sync/permissions/types.py +0 -0
- {src_auth_perms_sync-0.6.0 → src_auth_perms_sync-0.7.0}/src/src_auth_perms_sync/permissions/workflow.py +0 -0
- {src_auth_perms_sync-0.6.0 → src_auth_perms_sync-0.7.0}/src/src_auth_perms_sync/shared/__init__.py +0 -0
- {src_auth_perms_sync-0.6.0 → src_auth_perms_sync-0.7.0}/src/src_auth_perms_sync/shared/backups.py +0 -0
- {src_auth_perms_sync-0.6.0 → src_auth_perms_sync-0.7.0}/src/src_auth_perms_sync/shared/site_config.py +0 -0
- {src_auth_perms_sync-0.6.0 → src_auth_perms_sync-0.7.0}/tests/README.md +0 -0
- {src_auth_perms_sync-0.6.0 → src_auth_perms_sync-0.7.0}/tests/__init__.py +0 -0
- {src_auth_perms_sync-0.6.0 → src_auth_perms_sync-0.7.0}/tests/e2e/__init__.py +0 -0
- {src_auth_perms_sync-0.6.0 → src_auth_perms_sync-0.7.0}/tests/e2e/fixtures/add-users-by-email-and-list/after.json +0 -0
- {src_auth_perms_sync-0.6.0 → src_auth_perms_sync-0.7.0}/tests/e2e/fixtures/add-users-by-email-and-list/before.json +0 -0
- {src_auth_perms_sync-0.6.0 → src_auth_perms_sync-0.7.0}/tests/e2e/fixtures/add-users-by-email-and-list/maps.yaml +0 -0
- {src_auth_perms_sync-0.6.0 → src_auth_perms_sync-0.7.0}/tests/e2e/fixtures/add-users-preserves-existing/after.json +0 -0
- {src_auth_perms_sync-0.6.0 → src_auth_perms_sync-0.7.0}/tests/e2e/fixtures/add-users-preserves-existing/before.json +0 -0
- {src_auth_perms_sync-0.6.0 → src_auth_perms_sync-0.7.0}/tests/e2e/fixtures/add-users-preserves-existing/maps.yaml +0 -0
- {src_auth_perms_sync-0.6.0 → src_auth_perms_sync-0.7.0}/tests/e2e/fixtures/and-filters-intersect/after.json +0 -0
- {src_auth_perms_sync-0.6.0 → src_auth_perms_sync-0.7.0}/tests/e2e/fixtures/and-filters-intersect/before.json +0 -0
- {src_auth_perms_sync-0.6.0 → src_auth_perms_sync-0.7.0}/tests/e2e/fixtures/and-filters-intersect/maps.yaml +0 -0
- {src_auth_perms_sync-0.6.0 → src_auth_perms_sync-0.7.0}/tests/e2e/fixtures/empty-maps-noop/before.json +0 -0
- {src_auth_perms_sync-0.6.0 → src_auth_perms_sync-0.7.0}/tests/e2e/fixtures/empty-maps-noop/maps.yaml +0 -0
- {src_auth_perms_sync-0.6.0 → src_auth_perms_sync-0.7.0}/tests/e2e/fixtures/full-overwrite-dry-run/before.json +0 -0
- {src_auth_perms_sync-0.6.0 → src_auth_perms_sync-0.7.0}/tests/e2e/fixtures/full-overwrite-dry-run/maps.yaml +0 -0
- {src_auth_perms_sync-0.6.0 → src_auth_perms_sync-0.7.0}/tests/e2e/fixtures/full-overwrite-preserves-pending/after.json +0 -0
- {src_auth_perms_sync-0.6.0 → src_auth_perms_sync-0.7.0}/tests/e2e/fixtures/full-overwrite-preserves-pending/before.json +0 -0
- {src_auth_perms_sync-0.6.0 → src_auth_perms_sync-0.7.0}/tests/e2e/fixtures/full-overwrite-preserves-pending/maps.yaml +0 -0
- {src_auth_perms_sync-0.6.0 → src_auth_perms_sync-0.7.0}/tests/e2e/fixtures/full-overwrite-removes-stale-grant/after.json +0 -0
- {src_auth_perms_sync-0.6.0 → src_auth_perms_sync-0.7.0}/tests/e2e/fixtures/full-overwrite-removes-stale-grant/before.json +0 -0
- {src_auth_perms_sync-0.6.0 → src_auth_perms_sync-0.7.0}/tests/e2e/fixtures/full-overwrite-removes-stale-grant/maps.yaml +0 -0
- {src_auth_perms_sync-0.6.0 → src_auth_perms_sync-0.7.0}/tests/e2e/fixtures/full-overwrite-unions/after.json +0 -0
- {src_auth_perms_sync-0.6.0 → src_auth_perms_sync-0.7.0}/tests/e2e/fixtures/full-overwrite-unions/before.json +0 -0
- {src_auth_perms_sync-0.6.0 → src_auth_perms_sync-0.7.0}/tests/e2e/fixtures/full-overwrite-unions/maps.yaml +0 -0
- {src_auth_perms_sync-0.6.0 → src_auth_perms_sync-0.7.0}/tests/e2e/fixtures/full-overwrite-with-backup/after.json +0 -0
- {src_auth_perms_sync-0.6.0 → src_auth_perms_sync-0.7.0}/tests/e2e/fixtures/full-overwrite-with-backup/before.json +0 -0
- {src_auth_perms_sync-0.6.0 → src_auth_perms_sync-0.7.0}/tests/e2e/fixtures/full-overwrite-with-backup/maps.yaml +0 -0
- {src_auth_perms_sync-0.6.0 → src_auth_perms_sync-0.7.0}/tests/e2e/fixtures/get-full-snapshot/before.json +0 -0
- {src_auth_perms_sync-0.6.0 → src_auth_perms_sync-0.7.0}/tests/e2e/fixtures/get-repos-without-explicit-perms/before.json +0 -0
- {src_auth_perms_sync-0.6.0 → src_auth_perms_sync-0.7.0}/tests/e2e/fixtures/get-user-grants/before.json +0 -0
- {src_auth_perms_sync-0.6.0 → src_auth_perms_sync-0.7.0}/tests/e2e/fixtures/invalid-bad-regex/before.json +0 -0
- {src_auth_perms_sync-0.6.0 → src_auth_perms_sync-0.7.0}/tests/e2e/fixtures/invalid-bad-regex/maps.yaml +0 -0
- {src_auth_perms_sync-0.6.0 → src_auth_perms_sync-0.7.0}/tests/e2e/fixtures/invalid-missing-repos-section/before.json +0 -0
- {src_auth_perms_sync-0.6.0 → src_auth_perms_sync-0.7.0}/tests/e2e/fixtures/invalid-missing-repos-section/maps.yaml +0 -0
- {src_auth_perms_sync-0.6.0 → src_auth_perms_sync-0.7.0}/tests/e2e/fixtures/invalid-restore-wrong-schema-version/before.json +0 -0
- {src_auth_perms_sync-0.6.0 → src_auth_perms_sync-0.7.0}/tests/e2e/fixtures/invalid-restore-wrong-schema-version/snapshot.json +0 -0
- {src_auth_perms_sync-0.6.0 → src_auth_perms_sync-0.7.0}/tests/e2e/fixtures/invalid-set-created-after-date/before.json +0 -0
- {src_auth_perms_sync-0.6.0 → src_auth_perms_sync-0.7.0}/tests/e2e/fixtures/invalid-set-created-after-date/maps.yaml +0 -0
- {src_auth_perms_sync-0.6.0 → src_auth_perms_sync-0.7.0}/tests/e2e/fixtures/invalid-set-repos-created-after-date/before.json +0 -0
- {src_auth_perms_sync-0.6.0 → src_auth_perms_sync-0.7.0}/tests/e2e/fixtures/invalid-set-repos-created-after-date/maps.yaml +0 -0
- {src_auth_perms_sync-0.6.0 → src_auth_perms_sync-0.7.0}/tests/e2e/fixtures/invalid-set-unknown-repo/before.json +0 -0
- {src_auth_perms_sync-0.6.0 → src_auth_perms_sync-0.7.0}/tests/e2e/fixtures/invalid-set-unknown-repo/maps.yaml +0 -0
- {src_auth_perms_sync-0.6.0 → src_auth_perms_sync-0.7.0}/tests/e2e/fixtures/invalid-set-unknown-user/before.json +0 -0
- {src_auth_perms_sync-0.6.0 → src_auth_perms_sync-0.7.0}/tests/e2e/fixtures/invalid-set-unknown-user/maps.yaml +0 -0
- {src_auth_perms_sync-0.6.0 → src_auth_perms_sync-0.7.0}/tests/e2e/fixtures/invalid-unknown-selector-field/before.json +0 -0
- {src_auth_perms_sync-0.6.0 → src_auth_perms_sync-0.7.0}/tests/e2e/fixtures/invalid-unknown-selector-field/maps.yaml +0 -0
- {src_auth_perms_sync-0.6.0 → src_auth_perms_sync-0.7.0}/tests/e2e/fixtures/match-provider-and-host-fields/after.json +0 -0
- {src_auth_perms_sync-0.6.0 → src_auth_perms_sync-0.7.0}/tests/e2e/fixtures/match-provider-and-host-fields/before.json +0 -0
- {src_auth_perms_sync-0.6.0 → src_auth_perms_sync-0.7.0}/tests/e2e/fixtures/match-provider-and-host-fields/maps.yaml +0 -0
- {src_auth_perms_sync-0.6.0 → src_auth_perms_sync-0.7.0}/tests/e2e/fixtures/no-match-noop/before.json +0 -0
- {src_auth_perms_sync-0.6.0 → src_auth_perms_sync-0.7.0}/tests/e2e/fixtures/no-match-noop/maps.yaml +0 -0
- {src_auth_perms_sync-0.6.0 → src_auth_perms_sync-0.7.0}/tests/e2e/fixtures/regex-filters-scope/after.json +0 -0
- {src_auth_perms_sync-0.6.0 → src_auth_perms_sync-0.7.0}/tests/e2e/fixtures/regex-filters-scope/before.json +0 -0
- {src_auth_perms_sync-0.6.0 → src_auth_perms_sync-0.7.0}/tests/e2e/fixtures/regex-filters-scope/maps.yaml +0 -0
- {src_auth_perms_sync-0.6.0 → src_auth_perms_sync-0.7.0}/tests/e2e/fixtures/restore-applies-snapshot/after.json +0 -0
- {src_auth_perms_sync-0.6.0 → src_auth_perms_sync-0.7.0}/tests/e2e/fixtures/restore-applies-snapshot/before.json +0 -0
- {src_auth_perms_sync-0.6.0 → src_auth_perms_sync-0.7.0}/tests/e2e/fixtures/restore-applies-snapshot/snapshot.json +0 -0
- {src_auth_perms_sync-0.6.0 → src_auth_perms_sync-0.7.0}/tests/e2e/fixtures/restore-dry-run-noop/before.json +0 -0
- {src_auth_perms_sync-0.6.0 → src_auth_perms_sync-0.7.0}/tests/e2e/fixtures/restore-dry-run-noop/snapshot.json +0 -0
- {src_auth_perms_sync-0.6.0 → src_auth_perms_sync-0.7.0}/tests/e2e/fixtures/restore-missing-file/before.json +0 -0
- {src_auth_perms_sync-0.6.0 → src_auth_perms_sync-0.7.0}/tests/e2e/fixtures/restore-restores-pending/after.json +0 -0
- {src_auth_perms_sync-0.6.0 → src_auth_perms_sync-0.7.0}/tests/e2e/fixtures/restore-restores-pending/before.json +0 -0
- {src_auth_perms_sync-0.6.0 → src_auth_perms_sync-0.7.0}/tests/e2e/fixtures/restore-restores-pending/snapshot.json +0 -0
- {src_auth_perms_sync-0.6.0 → src_auth_perms_sync-0.7.0}/tests/e2e/fixtures/saml-group-filter/after.json +0 -0
- {src_auth_perms_sync-0.6.0 → src_auth_perms_sync-0.7.0}/tests/e2e/fixtures/saml-group-filter/before.json +0 -0
- {src_auth_perms_sync-0.6.0 → src_auth_perms_sync-0.7.0}/tests/e2e/fixtures/saml-group-filter/maps.yaml +0 -0
- {src_auth_perms_sync-0.6.0 → src_auth_perms_sync-0.7.0}/tests/e2e/fixtures/saml-group-live/after.json +0 -0
- {src_auth_perms_sync-0.6.0 → src_auth_perms_sync-0.7.0}/tests/e2e/fixtures/saml-group-live/before.json +0 -0
- {src_auth_perms_sync-0.6.0 → src_auth_perms_sync-0.7.0}/tests/e2e/fixtures/saml-group-live/maps.yaml +0 -0
- {src_auth_perms_sync-0.6.0 → src_auth_perms_sync-0.7.0}/tests/e2e/fixtures/set-created-after-sync-saml-orgs-dry-run/maps.yaml +0 -0
- {src_auth_perms_sync-0.6.0 → src_auth_perms_sync-0.7.0}/tests/e2e/fixtures/set-created-after-temp-user/after.json +0 -0
- {src_auth_perms_sync-0.6.0 → src_auth_perms_sync-0.7.0}/tests/e2e/fixtures/set-created-after-temp-user/before.json +0 -0
- {src_auth_perms_sync-0.6.0 → src_auth_perms_sync-0.7.0}/tests/e2e/fixtures/set-created-after-temp-user/maps.yaml +0 -0
- {src_auth_perms_sync-0.6.0 → src_auth_perms_sync-0.7.0}/tests/e2e/fixtures/set-full-sync-saml-orgs-dry-run/maps.yaml +0 -0
- {src_auth_perms_sync-0.6.0 → src_auth_perms_sync-0.7.0}/tests/e2e/fixtures/set-repos-created-after/after.json +0 -0
- {src_auth_perms_sync-0.6.0 → src_auth_perms_sync-0.7.0}/tests/e2e/fixtures/set-repos-created-after/before.json +0 -0
- {src_auth_perms_sync-0.6.0 → src_auth_perms_sync-0.7.0}/tests/e2e/fixtures/set-repos-created-after/maps.yaml +0 -0
- {src_auth_perms_sync-0.6.0 → src_auth_perms_sync-0.7.0}/tests/e2e/fixtures/set-repos-created-after-noop/before.json +0 -0
- {src_auth_perms_sync-0.6.0 → src_auth_perms_sync-0.7.0}/tests/e2e/fixtures/set-repos-created-after-noop/maps.yaml +0 -0
- {src_auth_perms_sync-0.6.0 → src_auth_perms_sync-0.7.0}/tests/e2e/fixtures/set-repos-created-after-sync-saml-orgs-dry-run/maps.yaml +0 -0
- {src_auth_perms_sync-0.6.0 → src_auth_perms_sync-0.7.0}/tests/e2e/fixtures/set-repos-filter/after.json +0 -0
- {src_auth_perms_sync-0.6.0 → src_auth_perms_sync-0.7.0}/tests/e2e/fixtures/set-repos-filter/before.json +0 -0
- {src_auth_perms_sync-0.6.0 → src_auth_perms_sync-0.7.0}/tests/e2e/fixtures/set-repos-filter/maps.yaml +0 -0
- {src_auth_perms_sync-0.6.0 → src_auth_perms_sync-0.7.0}/tests/e2e/fixtures/set-repos-sync-saml-orgs-dry-run/maps.yaml +0 -0
- {src_auth_perms_sync-0.6.0 → src_auth_perms_sync-0.7.0}/tests/e2e/fixtures/set-repos-without-explicit-perms/after.json +0 -0
- {src_auth_perms_sync-0.6.0 → src_auth_perms_sync-0.7.0}/tests/e2e/fixtures/set-repos-without-explicit-perms/before.json +0 -0
- {src_auth_perms_sync-0.6.0 → src_auth_perms_sync-0.7.0}/tests/e2e/fixtures/set-repos-without-explicit-perms/maps.yaml +0 -0
- {src_auth_perms_sync-0.6.0 → src_auth_perms_sync-0.7.0}/tests/e2e/fixtures/set-repos-without-perms-sync-saml-orgs-dry-run/maps.yaml +0 -0
- {src_auth_perms_sync-0.6.0 → src_auth_perms_sync-0.7.0}/tests/e2e/fixtures/set-users-created-after/after.json +0 -0
- {src_auth_perms_sync-0.6.0 → src_auth_perms_sync-0.7.0}/tests/e2e/fixtures/set-users-created-after/before.json +0 -0
- {src_auth_perms_sync-0.6.0 → src_auth_perms_sync-0.7.0}/tests/e2e/fixtures/set-users-created-after/maps.yaml +0 -0
- {src_auth_perms_sync-0.6.0 → src_auth_perms_sync-0.7.0}/tests/e2e/fixtures/set-users-created-after-noop/before.json +0 -0
- {src_auth_perms_sync-0.6.0 → src_auth_perms_sync-0.7.0}/tests/e2e/fixtures/set-users-created-after-noop/maps.yaml +0 -0
- {src_auth_perms_sync-0.6.0 → src_auth_perms_sync-0.7.0}/tests/e2e/fixtures/set-users-sync-saml-orgs-dry-run/maps.yaml +0 -0
- {src_auth_perms_sync-0.6.0 → src_auth_perms_sync-0.7.0}/tests/e2e/fixtures/set-users-without-explicit-perms/after.json +0 -0
- {src_auth_perms_sync-0.6.0 → src_auth_perms_sync-0.7.0}/tests/e2e/fixtures/set-users-without-explicit-perms/before.json +0 -0
- {src_auth_perms_sync-0.6.0 → src_auth_perms_sync-0.7.0}/tests/e2e/fixtures/set-users-without-explicit-perms/maps.yaml +0 -0
- {src_auth_perms_sync-0.6.0 → src_auth_perms_sync-0.7.0}/tests/e2e/fixtures/set-users-without-explicit-perms-default-batch/after.json +0 -0
- {src_auth_perms_sync-0.6.0 → src_auth_perms_sync-0.7.0}/tests/e2e/fixtures/set-users-without-explicit-perms-default-batch/before.json +0 -0
- {src_auth_perms_sync-0.6.0 → src_auth_perms_sync-0.7.0}/tests/e2e/fixtures/set-users-without-explicit-perms-default-batch/maps.yaml +0 -0
- {src_auth_perms_sync-0.6.0 → src_auth_perms_sync-0.7.0}/tests/e2e/fixtures/set-users-without-perms-sync-saml-orgs-dry-run/maps.yaml +0 -0
- {src_auth_perms_sync-0.6.0 → src_auth_perms_sync-0.7.0}/tests/e2e/test_local_cases.py +0 -0
- {src_auth_perms_sync-0.6.0 → src_auth_perms_sync-0.7.0}/tests/integration/__init__.py +0 -0
- {src_auth_perms_sync-0.6.0 → src_auth_perms_sync-0.7.0}/tests/integration/test_cli_entrypoint.py +0 -0
- {src_auth_perms_sync-0.6.0 → src_auth_perms_sync-0.7.0}/tests/setup.py +0 -0
- {src_auth_perms_sync-0.6.0 → src_auth_perms_sync-0.7.0}/tests/setup.yaml +0 -0
- {src_auth_perms_sync-0.6.0 → src_auth_perms_sync-0.7.0}/tests/unit/__init__.py +0 -0
- {src_auth_perms_sync-0.6.0 → src_auth_perms_sync-0.7.0}/tests/unit/test_apply.py +0 -0
- {src_auth_perms_sync-0.6.0 → src_auth_perms_sync-0.7.0}/tests/unit/test_backups.py +0 -0
- {src_auth_perms_sync-0.6.0 → src_auth_perms_sync-0.7.0}/tests/unit/test_command_additive.py +0 -0
- {src_auth_perms_sync-0.6.0 → src_auth_perms_sync-0.7.0}/tests/unit/test_mapping_rules.py +0 -0
- {src_auth_perms_sync-0.6.0 → src_auth_perms_sync-0.7.0}/tests/unit/test_maps.py +0 -0
- {src_auth_perms_sync-0.6.0 → src_auth_perms_sync-0.7.0}/tests/unit/test_module_api.py +0 -0
- {src_auth_perms_sync-0.6.0 → src_auth_perms_sync-0.7.0}/tests/unit/test_permissions_sourcegraph.py +0 -0
- {src_auth_perms_sync-0.6.0 → src_auth_perms_sync-0.7.0}/tests/unit/test_restore.py +0 -0
- {src_auth_perms_sync-0.6.0 → src_auth_perms_sync-0.7.0}/tests/unit/test_snapshot.py +0 -0
- {src_auth_perms_sync-0.6.0 → src_auth_perms_sync-0.7.0}/uv.lock +0 -0
|
@@ -127,6 +127,7 @@ jobs:
|
|
|
127
127
|
runs-on: ubuntu-24.04
|
|
128
128
|
env:
|
|
129
129
|
MARKDOWNLINT_CLI2_VERSION: "0.22.1"
|
|
130
|
+
MARKDOWNLINT_RELATIVE_LINKS_VERSION: "5.1.0"
|
|
130
131
|
|
|
131
132
|
steps:
|
|
132
133
|
- name: Check out code
|
|
@@ -139,10 +140,14 @@ jobs:
|
|
|
139
140
|
uses: actions/cache@v5
|
|
140
141
|
with:
|
|
141
142
|
path: ~/.npm
|
|
142
|
-
key: npm-${{ runner.os }}-markdownlint-cli2-${{ env.MARKDOWNLINT_CLI2_VERSION }}
|
|
143
|
+
key: npm-${{ runner.os }}-markdownlint-cli2-${{ env.MARKDOWNLINT_CLI2_VERSION }}-relative-links-${{ env.MARKDOWNLINT_RELATIVE_LINKS_VERSION }}
|
|
143
144
|
|
|
144
145
|
- name: Lint Markdown
|
|
145
|
-
run:
|
|
146
|
+
run: >
|
|
147
|
+
npx --yes
|
|
148
|
+
-p "markdownlint-cli2@${MARKDOWNLINT_CLI2_VERSION}"
|
|
149
|
+
-p "markdownlint-rule-relative-links@${MARKDOWNLINT_RELATIVE_LINKS_VERSION}"
|
|
150
|
+
markdownlint-cli2
|
|
146
151
|
|
|
147
152
|
python:
|
|
148
153
|
name: Validate Python
|
|
@@ -7,13 +7,13 @@ __pycache__
|
|
|
7
7
|
.pytest_cache
|
|
8
8
|
.ruff_cache
|
|
9
9
|
.venv
|
|
10
|
+
node_modules/
|
|
10
11
|
*.env*
|
|
11
12
|
*.gql
|
|
12
13
|
*.py[cod]
|
|
13
14
|
*.py[oc]
|
|
14
15
|
*.swp
|
|
15
16
|
*.tsv
|
|
16
|
-
*.yaml
|
|
17
17
|
build/
|
|
18
18
|
dist/
|
|
19
19
|
logs*/
|
|
@@ -22,7 +22,4 @@ src-auth-perms-sync-runs/
|
|
|
22
22
|
wheels/
|
|
23
23
|
|
|
24
24
|
# Allow
|
|
25
|
-
|
|
26
|
-
!.markdownlint-cli2.yaml
|
|
27
|
-
!maps-example.yaml
|
|
28
|
-
!tests/**/*.yaml
|
|
25
|
+
!examples/
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
globs:
|
|
2
|
+
- "**/*.md"
|
|
3
|
+
ignores:
|
|
4
|
+
- ".venv/**"
|
|
5
|
+
- "build/**"
|
|
6
|
+
- "dist/**"
|
|
7
|
+
- "node_modules/**"
|
|
8
|
+
modulePaths:
|
|
9
|
+
- "./node_modules"
|
|
10
|
+
customRules:
|
|
11
|
+
- markdownlint-rule-relative-links
|
|
12
|
+
config:
|
|
13
|
+
MD013:
|
|
14
|
+
line_length: 100
|
|
15
|
+
relative-links: true
|
|
@@ -12,7 +12,11 @@
|
|
|
12
12
|
actionlint
|
|
13
13
|
|
|
14
14
|
### Markdown files
|
|
15
|
-
npx --yes markdownlint-cli2@0.22.1
|
|
15
|
+
npx --yes -p markdownlint-cli2@0.22.1 -p markdownlint-rule-relative-links@5.1.0 markdownlint-cli2
|
|
16
|
+
|
|
17
|
+
### Confusable Unicode characters in non-Python files
|
|
18
|
+
# (ruff RUF001-RUF003 covers Python strings/comments/docstrings)
|
|
19
|
+
uv run python tests/confusables.py
|
|
16
20
|
|
|
17
21
|
### Python files
|
|
18
22
|
|
|
@@ -37,7 +41,8 @@ own checks.
|
|
|
37
41
|
|
|
38
42
|
```bash
|
|
39
43
|
# Fast, no network (also what the pre-commit hook runs):
|
|
40
|
-
# lint, format, pyright, unit + fixture
|
|
44
|
+
# lint, format, pyright, confusable-character scan, unit + fixture
|
|
45
|
+
# tests, CLI rejection matrix,
|
|
41
46
|
# randomized permission invariants
|
|
42
47
|
uv run tests/run.py
|
|
43
48
|
|
|
@@ -97,7 +102,7 @@ uv run ruff format --check src/src_auth_perms_sync/ tests/
|
|
|
97
102
|
uv run pyright
|
|
98
103
|
uv run python -m unittest discover -s tests
|
|
99
104
|
uv run src-auth-perms-sync --help
|
|
100
|
-
npx --yes markdownlint-cli2@0.22.1
|
|
105
|
+
npx --yes -p markdownlint-cli2@0.22.1 -p markdownlint-rule-relative-links@5.1.0 markdownlint-cli2
|
|
101
106
|
uv build --wheel --sdist --out-dir /tmp/src-auth-perms-sync-release-check --no-create-gitignore
|
|
102
107
|
rm -rf /tmp/src-auth-perms-sync-release-check
|
|
103
108
|
```
|
|
@@ -252,6 +257,10 @@ removed names like `ev`, `ex`, `exc`, `cfg`, `conn`, `resp`, `fn`,
|
|
|
252
257
|
|
|
253
258
|
Short names that ARE acceptable (don't rewrite these on sight):
|
|
254
259
|
|
|
260
|
+
- **Established domain abbreviations**: `org` / `orgs` for Sourcegraph
|
|
261
|
+
organizations, matching the `sync-saml-orgs` command, the `orgs/`
|
|
262
|
+
package, and the `sync_saml_orgs` config field. Do not expand these
|
|
263
|
+
back to `organization(s)` in identifiers.
|
|
255
264
|
- **TypedDict / dataclass fields that mirror the wire format**: `id`,
|
|
256
265
|
`url`, `kind` on `ExternalService` etc. These match GraphQL/JSON
|
|
257
266
|
keys and renaming would break the contract.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: src-auth-perms-sync
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.7.0
|
|
4
4
|
Summary: Set Sourcegraph permissions from authentication provider data
|
|
5
5
|
Project-URL: Homepage, https://github.com/sourcegraph/src-auth-perms-sync
|
|
6
6
|
Project-URL: Issues, https://github.com/sourcegraph/src-auth-perms-sync/issues
|
|
@@ -189,6 +189,11 @@ result = src.Set(config, mapping_rules=rules)
|
|
|
189
189
|
# result = src.SyncSamlOrgs(config)
|
|
190
190
|
```
|
|
191
191
|
|
|
192
|
+
The import API does not read environment variables or `.env` files on its
|
|
193
|
+
own — those apply to the CLI only. Pass every value explicitly to
|
|
194
|
+
`src.Config(...)` (read `os.environ` yourself if you want env-driven
|
|
195
|
+
configuration, as the example above does).
|
|
196
|
+
|
|
192
197
|
Module mode never touches your `logging` handlers or the root logger — your
|
|
193
198
|
application's logging config stays in charge. To see progress messages:
|
|
194
199
|
|
|
@@ -217,7 +222,7 @@ snapshots that make `--apply` reversible.
|
|
|
217
222
|
- Environment variables (CLI), or src.Config args (Python import)
|
|
218
223
|
- `SRC_ENDPOINT`
|
|
219
224
|
- `SRC_ACCESS_TOKEN` from a user with site-admin perms
|
|
220
|
-
- See [.env.example](
|
|
225
|
+
- See [.env.example](./examples/.env.example)
|
|
221
226
|
|
|
222
227
|
- YAML maps file
|
|
223
228
|
- By default: `src-auth-perms-sync-runs/<src_endpoint>/maps.yaml`
|
|
@@ -231,7 +236,7 @@ snapshots that make `--apply` reversible.
|
|
|
231
236
|
- Each mapping rule takes
|
|
232
237
|
- A map of filters for users
|
|
233
238
|
- A map of filters for repos
|
|
234
|
-
- See [maps
|
|
239
|
+
- See [maps.yaml](./examples/maps.yaml)
|
|
235
240
|
- An empty maps.yaml file is created for you on the first `get` run
|
|
236
241
|
|
|
237
242
|
## Usage: Permission sync
|
|
@@ -251,7 +256,7 @@ snapshots that make `--apply` reversible.
|
|
|
251
256
|
|
|
252
257
|
- Edit `src-auth-perms-sync-runs/<src_endpoint>/maps.yaml`
|
|
253
258
|
- Add mapping rules under the `maps:` top level key
|
|
254
|
-
- See [maps
|
|
259
|
+
- See [maps.yaml](./examples/maps.yaml)
|
|
255
260
|
|
|
256
261
|
3. **Set: Dry run**
|
|
257
262
|
|
|
@@ -292,7 +297,7 @@ snapshots that make `--apply` reversible.
|
|
|
292
297
|
1. **Get user and org metadata**
|
|
293
298
|
|
|
294
299
|
```bash
|
|
295
|
-
src-auth-perms-sync sync-saml-orgs
|
|
300
|
+
src-auth-perms-sync sync-saml-orgs --full
|
|
296
301
|
```
|
|
297
302
|
|
|
298
303
|
- Queries the Sourcegraph instance for auth providers, users, users' SAML groups, and orgs
|
|
@@ -301,12 +306,41 @@ snapshots that make `--apply` reversible.
|
|
|
301
306
|
2. **Apply org sync**
|
|
302
307
|
|
|
303
308
|
```bash
|
|
304
|
-
src-auth-perms-sync sync-saml-orgs --apply
|
|
309
|
+
src-auth-perms-sync sync-saml-orgs --full --apply
|
|
305
310
|
```
|
|
306
311
|
|
|
307
312
|
- Creates the orgs if they don't exist, and sync the members from the SAML groups to the orgs
|
|
308
313
|
- `--sync-saml-orgs` can also be added to a `set` run, to run both at the same time
|
|
309
314
|
|
|
315
|
+
3. **Scoped org sync for selected users**
|
|
316
|
+
|
|
317
|
+
```bash
|
|
318
|
+
src-auth-perms-sync sync-saml-orgs --users alice,bob
|
|
319
|
+
src-auth-perms-sync sync-saml-orgs --created-after 2026-06-01
|
|
320
|
+
src-auth-perms-sync sync-saml-orgs --users-without-explicit-perms
|
|
321
|
+
```
|
|
322
|
+
|
|
323
|
+
- Same user filters as `get` and `set`; a mode flag is required — there
|
|
324
|
+
is no bare `sync-saml-orgs`
|
|
325
|
+
|
|
326
|
+
### Org sync behavior
|
|
327
|
+
|
|
328
|
+
- Org names are `synced-<configID>-<group name>` (non-alphanumeric characters
|
|
329
|
+
become `-`). The `synced-` prefix marks tool ownership: the sync only ever
|
|
330
|
+
modifies orgs whose name carries it, so manually created orgs are never touched.
|
|
331
|
+
- The org sync mode is always explicit — no surprises:
|
|
332
|
+
- **Full** (`sync-saml-orgs --full`, or `set --full` / `--repos*`
|
|
333
|
+
`--sync-saml-orgs`): converges every synced org against all users. A synced
|
|
334
|
+
org whose SAML group disappeared has all members removed, but the org itself
|
|
335
|
+
is kept (its settings survive in case the group comes back).
|
|
336
|
+
- **Scoped** (user filters on `sync-saml-orgs`, or `set --users` /
|
|
337
|
+
`--users-without-explicit-perms` / `--created-after` with
|
|
338
|
+
`--sync-saml-orgs`): syncs org membership for exactly the selected users —
|
|
339
|
+
per-user additions AND removals, computed from each user's own SAML
|
|
340
|
+
assertion and org list. Other users' memberships never change, and no full
|
|
341
|
+
user scan or org member listing is needed, so API traffic stays
|
|
342
|
+
proportional to the selection.
|
|
343
|
+
|
|
310
344
|
## Options
|
|
311
345
|
|
|
312
346
|
Run `src-auth-perms-sync --help` for options
|
|
@@ -166,6 +166,11 @@ result = src.Set(config, mapping_rules=rules)
|
|
|
166
166
|
# result = src.SyncSamlOrgs(config)
|
|
167
167
|
```
|
|
168
168
|
|
|
169
|
+
The import API does not read environment variables or `.env` files on its
|
|
170
|
+
own — those apply to the CLI only. Pass every value explicitly to
|
|
171
|
+
`src.Config(...)` (read `os.environ` yourself if you want env-driven
|
|
172
|
+
configuration, as the example above does).
|
|
173
|
+
|
|
169
174
|
Module mode never touches your `logging` handlers or the root logger — your
|
|
170
175
|
application's logging config stays in charge. To see progress messages:
|
|
171
176
|
|
|
@@ -194,7 +199,7 @@ snapshots that make `--apply` reversible.
|
|
|
194
199
|
- Environment variables (CLI), or src.Config args (Python import)
|
|
195
200
|
- `SRC_ENDPOINT`
|
|
196
201
|
- `SRC_ACCESS_TOKEN` from a user with site-admin perms
|
|
197
|
-
- See [.env.example](
|
|
202
|
+
- See [.env.example](./examples/.env.example)
|
|
198
203
|
|
|
199
204
|
- YAML maps file
|
|
200
205
|
- By default: `src-auth-perms-sync-runs/<src_endpoint>/maps.yaml`
|
|
@@ -208,7 +213,7 @@ snapshots that make `--apply` reversible.
|
|
|
208
213
|
- Each mapping rule takes
|
|
209
214
|
- A map of filters for users
|
|
210
215
|
- A map of filters for repos
|
|
211
|
-
- See [maps
|
|
216
|
+
- See [maps.yaml](./examples/maps.yaml)
|
|
212
217
|
- An empty maps.yaml file is created for you on the first `get` run
|
|
213
218
|
|
|
214
219
|
## Usage: Permission sync
|
|
@@ -228,7 +233,7 @@ snapshots that make `--apply` reversible.
|
|
|
228
233
|
|
|
229
234
|
- Edit `src-auth-perms-sync-runs/<src_endpoint>/maps.yaml`
|
|
230
235
|
- Add mapping rules under the `maps:` top level key
|
|
231
|
-
- See [maps
|
|
236
|
+
- See [maps.yaml](./examples/maps.yaml)
|
|
232
237
|
|
|
233
238
|
3. **Set: Dry run**
|
|
234
239
|
|
|
@@ -269,7 +274,7 @@ snapshots that make `--apply` reversible.
|
|
|
269
274
|
1. **Get user and org metadata**
|
|
270
275
|
|
|
271
276
|
```bash
|
|
272
|
-
src-auth-perms-sync sync-saml-orgs
|
|
277
|
+
src-auth-perms-sync sync-saml-orgs --full
|
|
273
278
|
```
|
|
274
279
|
|
|
275
280
|
- Queries the Sourcegraph instance for auth providers, users, users' SAML groups, and orgs
|
|
@@ -278,12 +283,41 @@ snapshots that make `--apply` reversible.
|
|
|
278
283
|
2. **Apply org sync**
|
|
279
284
|
|
|
280
285
|
```bash
|
|
281
|
-
src-auth-perms-sync sync-saml-orgs --apply
|
|
286
|
+
src-auth-perms-sync sync-saml-orgs --full --apply
|
|
282
287
|
```
|
|
283
288
|
|
|
284
289
|
- Creates the orgs if they don't exist, and sync the members from the SAML groups to the orgs
|
|
285
290
|
- `--sync-saml-orgs` can also be added to a `set` run, to run both at the same time
|
|
286
291
|
|
|
292
|
+
3. **Scoped org sync for selected users**
|
|
293
|
+
|
|
294
|
+
```bash
|
|
295
|
+
src-auth-perms-sync sync-saml-orgs --users alice,bob
|
|
296
|
+
src-auth-perms-sync sync-saml-orgs --created-after 2026-06-01
|
|
297
|
+
src-auth-perms-sync sync-saml-orgs --users-without-explicit-perms
|
|
298
|
+
```
|
|
299
|
+
|
|
300
|
+
- Same user filters as `get` and `set`; a mode flag is required — there
|
|
301
|
+
is no bare `sync-saml-orgs`
|
|
302
|
+
|
|
303
|
+
### Org sync behavior
|
|
304
|
+
|
|
305
|
+
- Org names are `synced-<configID>-<group name>` (non-alphanumeric characters
|
|
306
|
+
become `-`). The `synced-` prefix marks tool ownership: the sync only ever
|
|
307
|
+
modifies orgs whose name carries it, so manually created orgs are never touched.
|
|
308
|
+
- The org sync mode is always explicit — no surprises:
|
|
309
|
+
- **Full** (`sync-saml-orgs --full`, or `set --full` / `--repos*`
|
|
310
|
+
`--sync-saml-orgs`): converges every synced org against all users. A synced
|
|
311
|
+
org whose SAML group disappeared has all members removed, but the org itself
|
|
312
|
+
is kept (its settings survive in case the group comes back).
|
|
313
|
+
- **Scoped** (user filters on `sync-saml-orgs`, or `set --users` /
|
|
314
|
+
`--users-without-explicit-perms` / `--created-after` with
|
|
315
|
+
`--sync-saml-orgs`): syncs org membership for exactly the selected users —
|
|
316
|
+
per-user additions AND removals, computed from each user's own SAML
|
|
317
|
+
assertion and org list. Other users' memberships never change, and no full
|
|
318
|
+
user scan or org member listing is needed, so API traffic stays
|
|
319
|
+
proportional to the selection.
|
|
320
|
+
|
|
287
321
|
## Options
|
|
288
322
|
|
|
289
323
|
Run `src-auth-perms-sync --help` for options
|
|
@@ -78,7 +78,7 @@ If/when we revisit:
|
|
|
78
78
|
|
|
79
79
|
Phase 1 now avoids per-repo username sets for non-overlapping full-set maps.
|
|
80
80
|
If memory remains too high after re-measuring, implement the Phase 2 grouped
|
|
81
|
-
plan in [mapping-efficiency.md](./mapping-efficiency.md): combine map-entry
|
|
81
|
+
plan in [mapping-efficiency.md](./memory-analysis/mapping-efficiency.md): combine map-entry
|
|
82
82
|
overlays into final groups of repos that share the same desired username tuple.
|
|
83
83
|
|
|
84
84
|
## Low priority: Expand group-membership filters beyond SAML
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# Engineering requests
|
|
2
2
|
|
|
3
3
|
Use this when opening Sourcegraph Engineering issues from memory-efficiency
|
|
4
|
-
evidence. Capture steps stay in [memory-efficiency.md](./memory-efficiency.md);
|
|
4
|
+
evidence. Capture steps stay in [memory-efficiency.md](./memory-analysis/memory-efficiency.md);
|
|
5
5
|
this file keeps the request-ready problem statement, evidence, proposed API
|
|
6
6
|
shape, and copy/paste issue text.
|
|
7
7
|
|
|
@@ -85,16 +85,16 @@ small `set` command. Instance: single `pgsql-0` on an 8-core node.
|
|
|
85
85
|
|
|
86
86
|
Observed during the concurrent captures:
|
|
87
87
|
|
|
88
|
-
- `pgsql-0` CPU (`kubectl top`): 7,636
|
|
89
|
-
- `frontend` / `gitserver` CPU: 124
|
|
88
|
+
- `pgsql-0` CPU (`kubectl top`): 7,636-7,683 millicores of 8,000 (saturated).
|
|
89
|
+
- `frontend` / `gitserver` CPU: 124-138m / 2-3m (idle bystanders).
|
|
90
90
|
- `pg_stat_activity`: 29 active statements, all
|
|
91
91
|
`permsStore.ListUserPermissions`, **zero wait events** — pure CPU, no lock
|
|
92
92
|
contention.
|
|
93
93
|
- `pg_stat_statements`: `permsStore.ListUserPermissions` at 24,026 calls,
|
|
94
94
|
27,635.6s total, 1,150ms mean.
|
|
95
|
-
- Per-client capture throughput: 23 users/sec solo → 2
|
|
95
|
+
- Per-client capture throughput: 23 users/sec solo → 2-4 users/sec at 4-way
|
|
96
96
|
concurrency.
|
|
97
|
-
- Aggregate throughput: 8
|
|
97
|
+
- Aggregate throughput: 8-16 users/sec at 4-way — **below the 23 users/sec a
|
|
98
98
|
single client achieves alone** (negative scaling).
|
|
99
99
|
- ALB (CloudWatch): no 5xx, no rejected connections — the edge and frontend
|
|
100
100
|
are not the bottleneck.
|
|
@@ -104,7 +104,7 @@ Observed during the concurrent captures:
|
|
|
104
104
|
Implications for the engineering request:
|
|
105
105
|
|
|
106
106
|
- A single per-user `permissionsInfo.repositories(source: API)` read costs
|
|
107
|
-
roughly 0.3
|
|
107
|
+
roughly 0.3-0.4s of Postgres CPU at this state size (1,150ms mean execution
|
|
108
108
|
under contention), so one operator at modest parallelism can saturate the
|
|
109
109
|
database by itself, and two concurrent operators degrade each other below
|
|
110
110
|
single-operator throughput.
|
|
@@ -112,7 +112,7 @@ Implications for the engineering request:
|
|
|
112
112
|
client read timeout, retries re-run the same expensive queries, adding load
|
|
113
113
|
exactly when the database is saturated.
|
|
114
114
|
- A bulk read API (one query returning explicit grants for many users or for
|
|
115
|
-
whole repos) would replace ~10,000
|
|
115
|
+
whole repos) would replace ~10,000 x ~1s statements per capture with a
|
|
116
116
|
single scan, and would also make concurrent operators viable.
|
|
117
117
|
|
|
118
118
|
## Sourcegraph codepath findings
|
|
@@ -142,7 +142,7 @@ from `github.com/sourcegraph/sourcegraph`:
|
|
|
142
142
|
## Presence-check resolver internals (2026-06-12)
|
|
143
143
|
|
|
144
144
|
Measured on the 10k-user / 50k-repo test instance, the presence probe
|
|
145
|
-
`User.permissionsInfo.repositories(source: API, first: 1)` costs 225
|
|
145
|
+
`User.permissionsInfo.repositories(source: API, first: 1)` costs 225-350ms of
|
|
146
146
|
server work per user, and alias batching barely helps (21,004 single-user
|
|
147
147
|
probes averaged 351.6ms; 25-user batches averaged 5,616ms ≈ 224.7ms/user). A
|
|
148
148
|
single `set --users-without-explicit-perms` run probing all 10,002 users at
|
|
@@ -180,7 +180,7 @@ Client-side mitigation shipped in `src-auth-perms-sync` (2026-06-12):
|
|
|
180
180
|
locally BEFORE probing, so probes scale with the rule-matched user count
|
|
181
181
|
instead of the instance's user count, and user hydration runs as aliased
|
|
182
182
|
25-user batches instead of one `UserByID` request per user. The remaining
|
|
183
|
-
inherent cost — ~225ms
|
|
183
|
+
inherent cost — ~225ms x probed user — is exactly what the
|
|
184
184
|
presence/filter API requested below would remove, and
|
|
185
185
|
`get --users-without-explicit-perms` still has to probe every active user
|
|
186
186
|
because its semantics are instance-wide.
|
{src_auth_perms_sync-0.6.0 → src_auth_perms_sync-0.7.0}/dev/memory-analysis/mapping-efficiency.md
RENAMED
|
@@ -64,7 +64,7 @@ user-group-b -> repo-group-2
|
|
|
64
64
|
Each `maps:` entry is naturally a grouped rule:
|
|
65
65
|
|
|
66
66
|
```text
|
|
67
|
-
selected users
|
|
67
|
+
selected users x selected repos
|
|
68
68
|
```
|
|
69
69
|
|
|
70
70
|
The maps schema keeps this restrictive: `users:` and `repos:` are selector
|
|
@@ -91,7 +91,7 @@ The old full-set planner immediately expanded every map entry into:
|
|
|
91
91
|
repo_id -> set(username)
|
|
92
92
|
```
|
|
93
93
|
|
|
94
|
-
That is expensive for rectangular maps such as `10000 users
|
|
94
|
+
That is expensive for rectangular maps such as `10000 users x 1000 repos`:
|
|
95
95
|
the username strings are shared, but each repo owns a large Python set with one
|
|
96
96
|
hash-table entry per planned grant.
|
|
97
97
|
|
{src_auth_perms_sync-0.6.0 → src_auth_perms_sync-0.7.0}/dev/memory-analysis/memory-efficiency.md
RENAMED
|
@@ -4,7 +4,7 @@ Use this when full snapshot capture or full-set apply is slow. The goal is to
|
|
|
4
4
|
correlate `src-auth-perms-sync` structured logs with Sourcegraph Jaeger spans
|
|
5
5
|
and pod/Postgres load. Request-ready evidence and copy/paste text for
|
|
6
6
|
Sourcegraph Engineering live in
|
|
7
|
-
[engineering-requests.md](
|
|
7
|
+
[engineering-requests.md](../engineering-requests.md).
|
|
8
8
|
|
|
9
9
|
## Capture a focused trace
|
|
10
10
|
|
|
@@ -157,7 +157,7 @@ The lower-level helper remains available for focused profiling outside a full
|
|
|
157
157
|
e2e run:
|
|
158
158
|
|
|
159
159
|
```bash
|
|
160
|
-
dev/memory-efficiency-monitor-sourcegraph.sh \
|
|
160
|
+
dev/memory-analysis/memory-efficiency-monitor-sourcegraph.sh \
|
|
161
161
|
--namespace m \
|
|
162
162
|
--output-dir /tmp/src-auth-perms-sync-sourcegraph-load-$(date -u +%Y%m%d-%H%M%S)
|
|
163
163
|
```
|
|
@@ -174,4 +174,4 @@ run.
|
|
|
174
174
|
|
|
175
175
|
Request-ready trace findings, stress evidence, Sourcegraph codepath notes,
|
|
176
176
|
proposed GraphQL APIs, and copy/paste issue text now live in
|
|
177
|
-
[engineering-requests.md](
|
|
177
|
+
[engineering-requests.md](../engineering-requests.md).
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# /// script
|
|
2
|
+
# requires-python = ">=3.11"
|
|
3
|
+
# dependencies = ["src-auth-perms-sync"]
|
|
4
|
+
# ///
|
|
5
|
+
"""Sync Sourcegraph repo permissions from your own Python code.
|
|
6
|
+
|
|
7
|
+
export SRC_ENDPOINT="https://sourcegraph.example.com"
|
|
8
|
+
export SRC_ACCESS_TOKEN="sgp_..." # site-admin token
|
|
9
|
+
uv run example-import.py
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
import logging
|
|
13
|
+
import os
|
|
14
|
+
|
|
15
|
+
import src_auth_perms_sync as src
|
|
16
|
+
|
|
17
|
+
# Configure your logger
|
|
18
|
+
logging.basicConfig(level=logging.INFO)
|
|
19
|
+
|
|
20
|
+
# The import API does not read environment variables or .env files on its
|
|
21
|
+
# own (the CLI does); pass every value explicitly.
|
|
22
|
+
config = src.Config(
|
|
23
|
+
src_endpoint=os.environ["SRC_ENDPOINT"],
|
|
24
|
+
src_access_token=os.environ["SRC_ACCESS_TOKEN"],
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
# Discover the instance's auth providers and code hosts
|
|
28
|
+
discovery = src.Get(config)
|
|
29
|
+
for auth_provider in discovery.auth_providers:
|
|
30
|
+
print("auth provider:", auth_provider.get("displayName"))
|
|
31
|
+
for code_host in discovery.code_hosts:
|
|
32
|
+
print("code host:", code_host.get("displayName"))
|
|
33
|
+
|
|
34
|
+
# Configure your mapping rules
|
|
35
|
+
mapping_rules: list[src.MappingRule] = [
|
|
36
|
+
{
|
|
37
|
+
"name": "LOB1-GROUP1 members get the LOB1-SA1 repos",
|
|
38
|
+
"users": {"authProvider": {"samlGroup": "LOB1-GROUP1"}},
|
|
39
|
+
"repos": {"codeHostConnection": {"username": "LOB1-SA1"}},
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
"name": "LOB2-GROUP2 members get the LOB2-SA2 repos",
|
|
43
|
+
"users": {"authProvider": {"samlGroup": "LOB2-GROUP2"}},
|
|
44
|
+
"repos": {"codeHostConnection": {"username": "LOB2-SA2"}},
|
|
45
|
+
},
|
|
46
|
+
]
|
|
47
|
+
|
|
48
|
+
# Run the set dry run, also syncing SAML groups to Sourcegraph organizations
|
|
49
|
+
result = src.Set(
|
|
50
|
+
config.model_copy(update={"full": True, "apply": False, "sync_saml_orgs": True}),
|
|
51
|
+
mapping_rules=mapping_rules,
|
|
52
|
+
)
|
|
53
|
+
# Print if it succeeded
|
|
54
|
+
print("permission sync dry run:", "ok" if result else "failed")
|
|
55
|
+
|
|
56
|
+
# Run the set apply, also syncing SAML groups to Sourcegraph organizations
|
|
57
|
+
result = src.Set(
|
|
58
|
+
config.model_copy(update={"full": True, "apply": True, "sync_saml_orgs": True}),
|
|
59
|
+
mapping_rules=mapping_rules,
|
|
60
|
+
)
|
|
61
|
+
|
|
62
|
+
# Print if it succeeded
|
|
63
|
+
print("permission sync apply:", "ok" if result else "failed")
|