{"id":31131525,"url":"https://github.com/lus/kratos-readonly-traits","last_synced_at":"2026-01-03T14:02:17.373Z","repository":{"id":142950970,"uuid":"571666019","full_name":"lus/kratos-readonly-traits","owner":"lus","description":"A simple service to implement read-only traits in Ory Kratos","archived":false,"fork":false,"pushed_at":"2022-11-29T12:44:11.000Z","size":13,"stargazers_count":1,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"main","last_synced_at":"2024-06-20T21:11:15.624Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"unlicense","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/lus.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","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":"lus"}},"created_at":"2022-11-28T16:11:53.000Z","updated_at":"2024-04-20T19:12:27.000Z","dependencies_parsed_at":"2023-04-23T14:17:41.412Z","dependency_job_id":null,"html_url":"https://github.com/lus/kratos-readonly-traits","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/lus/kratos-readonly-traits","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lus%2Fkratos-readonly-traits","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lus%2Fkratos-readonly-traits/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lus%2Fkratos-readonly-traits/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lus%2Fkratos-readonly-traits/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/lus","download_url":"https://codeload.github.com/lus/kratos-readonly-traits/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lus%2Fkratos-readonly-traits/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":275706287,"owners_count":25513176,"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","status":"online","status_checked_at":"2025-09-18T02:00:09.552Z","response_time":77,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":[],"created_at":"2025-09-18T04:02:05.447Z","updated_at":"2025-09-18T04:03:57.997Z","avatar_url":"https://github.com/lus.png","language":"Go","funding_links":["https://github.com/sponsors/lus"],"categories":["Projects"],"sub_categories":["Ory Kratos"],"readme":"# kratos-readonly-traits\n\n`kratos-readonly-traits` is a simple service simplifying the implementation of read-only traits in\n[Ory Kratos](https://github.com/ory/kratos).\n\nIt works by exposing an endpoint called by Kratos as a blocking web hook during the settings flow.\n\n## Installation \u0026 Configuration\n\n### Docker\n\nA Docker image is automatically built and pushed to GHCR.\nA `docker-compose.yml` file may look like this:\n\n```yml\nservices:\n    kratos-readonly-traits:\n        image: ghcr.io/lus/kratos-readonly-traits:latest\n        restart: unless-stopped\n        ports:\n            # I do not recommend actually exposing this port to the internet.\n            # A better solution would be to put this service in a mutual Docker network with Kratos.\n            - 8080:8080\n        environment:\n            # By default the application runs in development mode.\n            # I highly recommend setting this value for production usage.\n            ENVIRONMENT: prod\n            # The minimum log level to print.\n            # Available values: 'trace', 'debug', 'info', 'warn', 'error', 'fatal', 'panic' and 'disabled'\n            # The default value is 'info'. I recommend leaving this as this will not clutter your console anyway.\n            LOG_LEVEL: info\n            # The address to bind the HTTP server to.\n            # The default value is :8080 (= 0.0.0.0:8080).\n            LISTEN_ADDRESS: :8080\n            # The message that will appear below the input field when trying to manipulate a read-only trait.\n            # The default value is 'This field is read-only.'.\n            ERROR_MESSAGE: This field is read-only.\n```\n\n### From source\n\nAfter making sure that [Go 1.19](https://go.dev/dl/) is installed, simply follow these steps:\n\n1. Clone the repository and enter the directory it got cloned to:\n    ```shell\n    git clone https://github.com/lus/kratos-readonly-traits \u0026\u0026 cd kratos-readonly-traits\n    ```\n2. Build the binary:\n    ```shell\n    go build -o server cmd/server/main.go\n    ```\n3. Make sure to set the environment variables according to your configuration. A `.env` file is supported natively:\n    ```\n    # By default the application runs in development mode.\n    # I highly recommend setting this value for production usage.\n    ENVIRONMENT: prod\n   \n    # The minimum log level to print.\n    # Available values: 'trace', 'debug', 'info', 'warn', 'error', 'fatal', 'panic' and 'disabled'\n    # The default value is 'info'. I recommend leaving this as this will not clutter your console anyway.\n    LOG_LEVEL: info\n   \n    # The address to bind the HTTP server to.\n    # The default value is :8080 (= 0.0.0.0:8080).\n    LISTEN_ADDRESS: :8080\n   \n    # The message that will appear below the input field when trying to manipulate a read-only trait.\n    # The default value is 'This field is read-only.'.\n    ERROR_MESSAGE: This field is read-only.\n    ```\n4. Run the application:\n    ```shell\n    ./server\n    ```\n\n## Getting started\n\n### Configure Kratos webhook\n\nIn order for this service to be able to interrupt the settings flow of Kratos, you need to configure a blocking webhook.\n\n1. Please create a `\u003csomething\u003e.jsonnet` file somewhere where Kratos can access it. It must look like this:\n    ```jsonnet\n    function(ctx) {\n        schema_url: ctx.identity.schema_url,\n        old_traits: ctx.flow.identity.traits,\n        new_traits: ctx.identity.traits\n    }\n    ```\n2. Adjust the configuration file of Kratos so that it contains a webhook configuration like this:\n    ```yml\n    selfservice:\n      flows:\n        settings:\n          after:\n            profile:\n              hooks:\n                - hook: web_hook\n                  config:\n                    url: http://\u003ckratos-readonly-traits\u003e:8080\n                    method: POST\n                    body: file:///path/to/\u003csomething\u003e.jsonnet\n                    can_interrupt: true\n    ```\n   \n### Adjust the identity schema\n\nThis service will not treat any trait as read-only by default.\nTo configure a read-only trait, simply add the `lus/kratos-readonly-traits.readonly` boolean to the identity schema:\n\n```json\n{\n    \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n    \"$id\": \"https://example.com/schemas/user.schema.json\",\n    \"title\": \"User\",\n    \"type\": \"object\",\n    \"properties\": {\n        \"traits\": {\n            \"type\": \"object\",\n            \"properties\": {\n                \"username\": {\n                    \"title\": \"Username\",\n                    \"type\": \"string\",\n                    \"minLength\": 1,\n                    \"maxLength\": 20,\n                    \"pattern\": \"^[a-z0-9]+$\",\n                    \"ory.sh/kratos\": {\n                        \"credentials\": {\n                            \"password\": {\n                                \"identifier\": true\n                            }\n                        }\n                    },\n                    \"lus/kratos-readonly-traits\": {\n                        \"readonly\": true\n                    }\n                },\n                \"email\": {\n                    \"title\": \"E-Mail\",\n                    \"type\": \"string\",\n                    \"format\": \"email\",\n                    \"ory.sh/kratos\": {\n                        \"credentials\": {\n                            \"password\": {\n                                \"identifier\": true\n                            }\n                        },\n                        \"recovery\": {\n                            \"via\": \"email\"\n                        },\n                        \"verification\": {\n                            \"via\": \"email\"\n                        }\n                    }\n                }\n            },\n            \"required\": [\n                \"username\",\n                \"email\"\n            ],\n            \"additionalProperties\": false\n        }\n    }\n}\n```\n\nThis schema will make the `username` trait read-only.\n\n## Support\n\nFeel free to open issues in this repository if you encounter any problem or want to suggest a feature.\nIf you want to ask a quick question, feel free to join my [Discord server](https://go.lus.pm/discord).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flus%2Fkratos-readonly-traits","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flus%2Fkratos-readonly-traits","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flus%2Fkratos-readonly-traits/lists"}