{"id":21508847,"url":"https://github.com/oddlama/kanidm-provision","last_synced_at":"2025-04-09T16:44:03.916Z","repository":{"id":226063477,"uuid":"767610498","full_name":"oddlama/kanidm-provision","owner":"oddlama","description":"A small utility to help with kanidm provisioning","archived":false,"fork":false,"pushed_at":"2025-03-21T15:58:36.000Z","size":134,"stargazers_count":42,"open_issues_count":6,"forks_count":6,"subscribers_count":4,"default_branch":"main","last_synced_at":"2025-03-23T18:54:15.639Z","etag":null,"topics":["kanidm","provisioning"],"latest_commit_sha":null,"homepage":"","language":"Nix","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/oddlama.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE-APACHE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":["oddlama"]}},"created_at":"2024-03-05T15:52:10.000Z","updated_at":"2025-03-21T15:58:38.000Z","dependencies_parsed_at":"2024-05-07T17:48:03.853Z","dependency_job_id":"07ab6130-f855-444b-a3b2-b8b87286b596","html_url":"https://github.com/oddlama/kanidm-provision","commit_stats":null,"previous_names":["oddlama/kanidm-provision"],"tags_count":5,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/oddlama%2Fkanidm-provision","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/oddlama%2Fkanidm-provision/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/oddlama%2Fkanidm-provision/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/oddlama%2Fkanidm-provision/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/oddlama","download_url":"https://codeload.github.com/oddlama/kanidm-provision/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248069667,"owners_count":21042681,"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":["kanidm","provisioning"],"created_at":"2024-11-23T21:13:05.490Z","updated_at":"2025-04-09T16:44:03.910Z","avatar_url":"https://github.com/oddlama.png","language":"Nix","funding_links":["https://github.com/sponsors/oddlama"],"categories":["Security"],"sub_categories":[],"readme":"[About](#-kanidm-provisioning-tool) \\| [Usage](#usage) \\| [JSON Schema](#json-schema)\n\n## 🦀 Kanidm Provisioning Tool\n\nThis is a tiny helper utility that uses kanidm's API to provision\nusers, groups and oauth2 systems. This tool is needed to allow declarative\nprovisioning of kanidm in NixOS, but can be used on any other system as well.\nThis tool is not affiliated with kanidm itself. Use at your own discretion.\n\nTwo optional patches are provided for kanidm that allow you to:\n- provision oauth2 basic secrets\n- use a specific password when recovering admin account credentials.\n\nCurrently this tool supports the following provisioning operations which should suffice for basic SSO and OIDC needs.\nPRs are of course welcome!\n\n| | Provisioning Feature\n---|---\n| |\n| 👪 | **Groups**\n| ✅ | Create/delete\n| ✅ | Members\n| ❌ | Unix attributes\n| |\n| 🧑 | **Persons**\n| ✅ | Create/delete\n| ✅ | Attributes (displayname, legalname, mail)\n| ❌ | Credentials\n| ❌ | SSH\n| ❌ | Unix attributes\n| ❌ | Radius\n| |\n| 🌐 | **Oauth2**\n| ✅ | Create/delete (basic, public)\n| ✅ | Attributes (origin url, origin landing, pkce enable, prefer short username)\n| ✅* | Basic secret\n| ✅ | Scope maps\n| ✅ | Supplementary scope maps\n| ✅ | Claim maps\n\n(*): Requires patch, [see below](#provisioning-oauth2-basic-secrets).\n\n## Usage\n\nBuild the utility simply by running:\n\n```bash\n\u003e cargo build\n```\n\nAfterwards you can apply a state file to your kanidm instance by executing:\n\n```bash\nKANIDM_PROVISION_IDM_ADMIN_TOKEN=\"your-idm-admin-token\" \\\n  kanidm-provision --url 'https://auth.example.com' --state state.json\n```\n\n## Orphan removal\n\nThis tool automatically adds all created entities to a tracking group so\nwhenever something is removed from the state file in the future, the change\ncan be reflected in kanidm automatically.\n\nTo prevent this kind of orphan removal, you can to pass `--no-auto-remove`.\nRemoving for example a group from the state file will then not cause any\nchanges in kanidm, unless the state file explicitly specifies `present: false`.\n\nThis automatic tracking does not work for oauth2 claim maps, since claim maps\nare not a separate entity in kanidm. To work around that, each oauth2 resource server\nhas a `removeOrphanedClaimMaps` option that will delete any claim maps on the resource\nserver that haven't been created by this tool. `--no-auto-remove` has no effect on that option.\n\n## Provisioning oauth2 basic secrets\n\nThis tool is able to provision basic secrets if you build kanidm\nwith the patch provided in [./patches](./patches). This adds a new endpoint\nthat allows modifying the basic secret of any oauth2 resource server via a new API endpoint,\ninstead of only allowing to read the value generated by kanidm.\n\nSome applications may have issues with certain characters appearing in the basic secret, especially with `\u0026` which\ncauses issues when the application does not properly urlencode the secret. While this is a bug\nin the application, you can prevent this from happening by generating new secret values with alphanumeric content:\n```\ntr --complement --delete 'ABCDEFGHJKLMNPQRSTUVWXYZabcdefghjkpqrstuvwxyz0123456789' \u003c /dev/urandom | head --bytes 48\n```\n\n\u003e \\[!CAUTION\\]\n\u003e You need to reset your kanidm database after applying these patches to the kanidm source code,\n\u003e otherwise the access control profile will not be updated and any call to the new endpoint will fail!\n\n## Provisioning (idm_)admin credentials\n\nThe second provided patch is a standalone kanidm patch that adds the ability to\nspecify a password when recovering account credentials. Useful to provision the\nidm_admin password and avoid dynamic state that needs to be known to run the\nprovisioning tool.\n\n```bash\nKANIDM_RECOVER_ACCOUNT_PASSWORD=V3kACDdwPjYUgYuLdlRfBqeBWf3TyJmv9h0f6CP3E3dv2B4S \\\n  kanidmd recover-account idm_admin --from-environment \u003e/dev/null\n```\n\n## JSON Schema\n\nThis is the schema consumed by this application.\n\nNote that all keys for `groups`, `persons` and `systems.oauth2` need to be in lowercase.\nE.g. `person1` is allowed, `Person1` or `pErSoN1` are not.\n\n```yaml\n{\n  # Specifies the provisioned groups\n  \"groups\": {\n    # One entry per group\n    \"group1\": {\n      # Optional. Defaults to true if not given.\n      # Whether the group should be present or absent.\n      \"present\": true,\n      # The exhaustive list of group members.\n      \"members\": [\n        \"person1\",\n        \"person2\",\n        \"group1\"\n      ]\n    },\n    # ...\n  },\n  # Specifies the provisioned persons\n  \"persons\": {\n    # One entry per person\n    \"person1\": {\n      # Optional. Defaults to true if not given.\n      # Whether the person should be present or absent.\n      \"present\": true,\n      # Required.\n      \"displayName\": \"Person1\",\n      # Optional.\n      \"legalName\": \"Per Son\",\n      # Optional.\n      \"mailAddresses\": [\n        \"person1@example.com\"\n        # ...\n      ],\n    },\n    # ...\n  },\n  \"systems\": {\n    \"oauth2\": {\n      # One entry per oauth2 resource server\n      \"forgejo\": {\n        # Optional. Defaults to true if not given.\n        # Whether the oauth2 resource server should be present or absent.\n        \"present\": true,\n        # Optional. Defaults to false if not given.\n        # Whether the oauth2 resource server should be a public one (i.e. no basic secret, enforces PKCE and can allow localhost redirect).\n        \"public\": false,\n        # Required.\n        \"displayName\": \"Forgejo\",\n        # Required. Must end with a '/'.\n        # Also accepts a non-empty list of strings if you want to set multiple origin urls.\n        # e.g. [\"https://git.example.com/\", \"https://git.example.de/\"]\n        \"originUrl\": \"https://git.example.com/\",\n        # Required. Landing page url (for web interface)\n        \"originLanding\": \"https://git.example.com/\",\n        # Optional. Only works when using the patch. Do not specify otherwise!\n        # Will set the basic secret to the contents of the given file. Whitespace will be trimmed from both ends.\n        # Only for non-public clients\n        \"basicSecretFile\": \"./secret1\",\n        # Optional. Application image to display in the WebUI.\n        # Kanidm supports \"image/jpeg\", \"image/png\", \"image/gif\", \"image/svg+xml\", and \"image/webp\"\n        # The image will be uploaded each time kanidm-provision is run\n        \"imageFile\": \"./forgejo.svg\",\n        # Optional. Defaults to false. Use name instead of spn for the preferred_username claim\n        \"preferShortUsername\": false,\n        # Optional. Defaults to false. Allows localhost redirects. Only for public resource servers.\n        \"enableLocalhostRedirects\": false,\n        # Optional. Defaults to false. Allows legacy jwt crypto like RS256.\n        \"enableLegacyCrypto\": false,\n        # Optional. Defaults to false. Disables PKCE for this resource server (can only be used on non-public resoure servers).\n        \"allowInsecureClientDisablePkce\": false,\n        # Optional.\n        # Scope maps will map kanidm groups to returned oauth scopes.\n        \"scopeMaps\": {\n          # One entry per scope map.\n          \"group1\": [\n            \"openid\",\n            \"email\",\n            \"profile\"\n          ]\n        },\n        # Optional.\n        # Supplementary scope maps will map kanidm groups to additionally returned oauth scopes.\n        \"supplementaryScopeMaps\": {\n          # One entry per supplementary scope map. Anything not specified here will not be touched.\n          # To remove an entry, assign the empty list.\n          \"group2\": [\n            \"additional_scope\"\n          ]\n        },\n        # Optional. Defaults to true.\n        # If true, any claim maps found on the resource server that are\n        # not explicitly specified in here will be removed.\n        \"removeOrphanedClaimMaps\": true,\n        # Optional.\n        # Claim maps will add a new claim with values depending on the\n        # kanidm groups of the authenticating party.\n        \"claimMaps\": {\n          # One entry per claim, the key is the new claim name.\n          \"groups\": {\n            # Required.\n            # The strategy used to join multiple values. One of:\n            #   - \"ssv\" (space separated: one two three)\n            #   - \"csv\" (comma separated: one,two,three)\n            #   - \"array\" (array notation: [\"one\", \"two\", \"three\"])\n            \"joinType\": \"array\",\n            # Assign values based on kanidm groups.\n            # At least one entry is required.\n            \"valuesByGroup\": {\n              \"group1\": [\n                \"user\"\n              ],\n              \"group2\": [\n                \"user\",\n                \"important_user\"\n              ],\n              \"group3\": [\n                \"admin\"\n              ]\n              # ...\n            }\n          }\n          # ...\n        }\n      }\n    }\n  }\n}\n```\n\n## License\n\nLicensed under either of\n\n- Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or \u003chttps://www.apache.org/licenses/LICENSE-2.0\u003e)\n- MIT license ([LICENSE-MIT](LICENSE-MIT) or \u003chttps://opensource.org/licenses/MIT\u003e)\n\nat your option.\nUnless you explicitly state otherwise, any contribution intentionally\nsubmitted for inclusion in this crate by you, as defined in the Apache-2.0 license,\nshall be dual licensed as above, without any additional terms or conditions.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Foddlama%2Fkanidm-provision","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Foddlama%2Fkanidm-provision","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Foddlama%2Fkanidm-provision/lists"}