{"id":32181504,"url":"https://github.com/neyho/eywa","last_synced_at":"2026-02-20T16:01:50.443Z","repository":{"id":194026849,"uuid":"689947555","full_name":"neyho/eywa","owner":"neyho","description":null,"archived":false,"fork":false,"pushed_at":"2026-02-17T13:52:38.000Z","size":35618,"stargazers_count":10,"open_issues_count":0,"forks_count":3,"subscribers_count":4,"default_branch":"master","last_synced_at":"2026-02-17T18:51:10.050Z","etag":null,"topics":["access-control","datasets","graphql","iam","modeling","oauth","openid","openid-connect","openid-server","openidconnect","pedestal","user-management"],"latest_commit_sha":null,"homepage":"https://neyho.github.io/eywa/","language":"Clojure","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/neyho.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"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,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2023-09-11T08:34:54.000Z","updated_at":"2026-02-17T13:52:42.000Z","dependencies_parsed_at":"2023-10-10T18:06:30.602Z","dependency_job_id":"b7fa70bf-a5d2-4c03-85bc-2f8886fde725","html_url":"https://github.com/neyho/eywa","commit_stats":null,"previous_names":["neyho/eywa-core","neyho/eywa"],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/neyho/eywa","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/neyho%2Feywa","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/neyho%2Feywa/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/neyho%2Feywa/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/neyho%2Feywa/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/neyho","download_url":"https://codeload.github.com/neyho/eywa/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/neyho%2Feywa/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29656589,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-20T09:27:29.698Z","status":"ssl_error","status_checked_at":"2026-02-20T09:26:12.373Z","response_time":59,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"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":["access-control","datasets","graphql","iam","modeling","oauth","openid","openid-connect","openid-server","openidconnect","pedestal","user-management"],"created_at":"2025-10-21T22:47:17.700Z","updated_at":"2026-02-20T16:01:50.437Z","avatar_url":"https://github.com/neyho.png","language":"Clojure","funding_links":[],"categories":[],"sub_categories":[],"readme":"\n\n\u003cp align=\"end\"\u003e\u003cimg src=\"https://www.eywaonline.com/eywa/logo/eywa.svg\" alt=\"Logo\" width=\"80\" /\u003e\u003c/div\u003e\n\nThe **EYWA project** is a fusion of **Identity Access Control** through OAuth2.1 (+OIDC) and deployable, exportable, transportable **Data Models**. Once deployed, these models are immediately exposed through **generic GraphQL queries and mutations**.\n\n- [Installation](#installation)\n- [Examples](https://github.com/neyho/eywa-examples)\n- [Frontend](https://github.com/neyho/eywa-frontend)\n- Motivation\n- Disclaimer\n\n#### Why?\n\nBecause it makes my day better. It won't fit every situation or scenario, but it can contribute at any point. Starting a new project often comes with repetitive requirements: **user management** and **database design**. Why not handle both simultaneously to take you as far as possible, as quickly as possible?\n\nThis is all available through a **graphical UI**. Visualizing how your data is structured, understanding relationships, and being able to share this view with your teammates ensures the entire team is on the same page. This process has led to **unexpected enhancements** and saved us from many **dead-end ideas**.\n\nWhen expanding the scope or redesigning data \"tables\" and \"columns\" don’t you want to see the impact your changes will have? Wouldn't it be better to see the differences between the current database state and the proposed future state? Do you really want to manually add or alter tables and columns?\n\n\n\n#### How?\n\nThe idea is simple: it all starts with **data modeling**. Data models consist of **entities** and **relations**, represented as Clojure records that implement protocols defined in the `neyho.eywa.dataset.core` namespace. These models work seamlessly with both Clojure and ClojureScript. This design ensures that data models are:\n\n- **Exportable** (via Transit)\n- **Importable** through the same engine\n\n\n##### Projection\n\nBoth **entity** and **relation** records implement the `ERDModelProjectionProtocol`. One of the key methods is `project`, which projects **this** onto **that**. \n\nImagine you have a globally active data model (`this`) and a new model (`that`). By projecting one onto the other, the projection highlights differences:\n\n- Was something **added**?\n- Was something **removed**?\n- Does something have a **diff**?\n\nFrom this point, it's just a matter of implementing the **DB DDL** to take control of the database.\n\n\n##### GraphQL\n\nGreat, now there are tables or spaces where data can be stored, and the structure is well-defined. What’s next? Interaction with the database through a few **generic methods**:\n\n- **`sync`**: Save data exactly as provided (data not provided remains unchanged).\n- **`stack`**: Similar to `sync`, but stacking preserves related data.\n- **`slice`**: Removes relations between entities.\n- **`delete`**: Deletes specific records.\n- **`purge`**: Mass delete—works like \"search \u0026 destroy.\"\n- **`get`**: Retrieves data starting from an exact record.\n- **`search`**: Retrieves data based on multiple records matching a condition.\n- **`get-tree`**: Retrieves data by traversing a recursive relation.\n- **`search-tree`**: Retrieves data by traversing a recursive relation for multiple matching records.\n\nEach **entity** can be managed using the methods above. For each entity, a corresponding GraphQL query or mutation is exposed when the data models are deployed.\n\n\n##### Extending\n\nEYWA is designed for extensibility. Even **eywa-core** extends itself for tasks not covered by the generic methods, such as deploying data models and subscribing to datamodel changes.\nTo extend GraphQL with custom fields, types, queries, or mutations, take a look at:\n\n```plaintext\nresources/datasets.graphql\n```\nIt can be imported and integrated into global GraphQL schema by using `neyho.eywa.lacinia/add-shard` function.\n\n\nEYWA simplifies complex workflows by combining **identity management** and **data modeling**, providing a foundation for rapid development with minimal overhead.\n\n\n\n---\n\n[![Clojars Project](https://img.shields.io/clojars/v/org.neyho/eywa-core.svg)](https://clojars.org/org.neyho/eywa-core)\n\u003c!-- [![Clojars Project](https://img.shields.io/clojars/v/org.neyho/eywa-core-frontend.svg)](https://clojars.org/org.neyho/eywa-core-frontend) --\u003e\n\n\n\u003cp align=\"center\"\u003e\u003cimg src=\"doc/img/eywa_modeling.png\" alt=\"Screenshot\"/\u003e\u003c/div\u003e\n\n## Quickstart\n\n### 🐳 Docker (Recommended for Showcase)\n\nThe fastest way to try EYWA is using Docker. This includes PostgreSQL, EYWA Core (IAM + Datacraft), and the frontend UI - everything you need in one command:\n\n```bash\n# Clone the repository\ngit clone https://github.com/neyho/eywa-core.git\ncd eywa-core\n\n# Start EYWA\ndocker-compose up -d\n\n# Access EYWA at http://localhost:8080/eywa/\n# Default credentials: admin / admin\n```\n\n**What's Included:**\n- ✅ **PostgreSQL 16** - Alpine-based database (267 MB)\n- ✅ **EYWA Core** - OAuth2.1 + OIDC + Datacraft (313 MB)\n- ✅ **Web UI** - Full graphical interface for data modeling\n- ✅ **Auto-initialization** - Database schemas, encryption, admin user\n- ✅ **OAuth Persistence** - Production-ready session management\n- 📦 **Total Size**: ~580 MB (compressed image layers)\n\n**First Run - Automatic Setup:**\nEYWA will automatically:\n- Start PostgreSQL database\n- Initialize IAM and Datacraft schemas\n- Configure encryption keys (auto-generated, persisted)\n- Set up OAuth persistence to database\n- Create admin user (username: `admin`, password: `admin`)\n- Serve the web UI from container at `/eywa/`\n\n**Configuration:**\nAll settings in `docker-compose.yml` can be customized:\n```yaml\n# Admin credentials (CHANGE FOR PRODUCTION!)\nADMIN_USERNAME: admin\nADMIN_PASSWORD: admin\n\n# Database settings\nPOSTGRES_PASSWORD: eywa\n\n# Custom encryption key (optional, auto-generated if not set)\nENCRYPTION_KEY: your-secure-key-here\n```\n\n**Useful Commands:**\n```bash\ndocker-compose logs -f eywa      # View EYWA logs\ndocker-compose logs -f postgres  # View database logs\ndocker-compose restart eywa      # Restart EYWA\ndocker-compose down              # Stop all services\ndocker-compose down -v           # Stop and remove data volumes\n```\n\n**Using Pre-built Image (Coming Soon):**\n```bash\n# Pull from Docker Hub (when published)\ndocker pull neyho/eywa-core:latest\ndocker-compose up -d\n```\n\nFor detailed Docker documentation, production deployment tips, and troubleshooting, see [docker/README.md](docker/README.md)\n\n---\n\n### 💻 Manual Installation\n\n#### Windows\n\n```ps1\n# Maybe you will have to disable executino policy\n# Set-ExecutionPolicy -ExecutionPolicy Bypass -Scope Process\nInvoke-WebRequest -Uri \"https://s3.eu-central-1.amazonaws.com/eywa.cli/install_eywa_cli.ps1\" -OutFile eywa_cli_install.ps1\n./eywa_cli_install.ps1\nrm eywa_cli_install.ps1\n```\n\n:::note Add following to PATH environment variable\n```text\n%USERPROFILE%\\.eywa\\bin\n``` \n:::\n\n\n#### Linux and MacOs\n```bash\ncurl -s https://s3.eu-central-1.amazonaws.com/eywa.cli/install_eywa_cli.sh | bash\n```\n\n\n#### Install DB\nCurrently supported database is Postgres, although support for MySQL, SQLite, XTDB and others is on roadmap. \n\nRequirement is to have Postgres, so if you don't have installation i recommend using docker to download Postgres\nimage and afterwards run:\n\n```text\ndocker run --name EYWA_DEV -p 5432:5432 -e POSTGRES_PASSWORD=password postgres\n```\n\nThis will spin up container with port forwarding so that you can connect to database on localhost using\npostgres user.\n\nNow we need to install eywa server jar file. Run\n```text\neywa server -l\n\n# And output should look something like this\nList of available versions. '*' installed, '-' not installed\n\n[*] 0.5.0\n[-] 0.4.1\n[-] 0.3.9\n[-] 0.3.7\n[-] 0.3.5\n[-] 0.3.4\n[-] 0.3.3\n[-] 0.3.2\n[-] 0.3.1\n[-] 0.3.0\n[-] 0.2.9\n```\n\nTo install some version run\n```text\neywa server -s 0.5.2\n```\n\neywa server server is installed, now we need to initialize EYWA IAM and Datacraft. So we should run:\n\n```text\neywa server init\n```\n\nIf above command didn't throw any error that implies that initialization was successfull and DB is initialized.\nSo everything is ready to start EYWA server, except there is no user that can login to EYWA.\n```text\neywa server super -s admin\n```\n\nWill prompt for password for admin password, and when supplied admin user will be created with target password.\nNow run:\n\n```text\neywa server start\n```\n\nAnd navigate to **https://my.eywaonline.com/eywa/** and login screen should be waiting for you. Use username and\npassword from previous step to login.\n\nTo track what is happening open log file at location __~/.eywa/logs/system.log__\n\n\nIf something went wrong or eywa server server isn't running as supposed to, run\n```text\neywa server doctor\n```\n\n\n#### CLI\n__eywa__ cli client can connect to EYWA server by running\n```text\neywa connect http://localhost:8080\n```\nYou will have to complete device code flow for target user and\nafter successfull connection client will use provided tokens to\ninteract with EYWA server.\n\nClient also supports executing scripts through\n```text\neywa run -c \"py example.py\"\n```\nThis will encapsulate running script process and by using one of\nsupported client libraries script can interact with connected EYWA\nserver with authorized EYWA user. The part above\n\nFor now we support:\n * Babashka [eywa-client](https://clojars.org/org.neyho/eywa-client)\n * Python - [eywa-client](https://pypi.org/project/eywa-client/)\n * Javascript - [eywa-client](https://www.npmjs.com/package/eywa-client)\n * Go  - [eywa-client](https://github.com/neyho/eywa-go/tree/main)\n * Ruby - [eywa-client](https://rubygems.org/gems/eywa-client/versions/0.3.0)\n\nEYWA can be controlled through environment variables as well. To see\nhow, run:\n\n```text\neywa server -h\n```\n\n\n## Environment\nControl EYWA with environment variables.\n\n##### EYWA_SERVE\nIt is possible to serve some folder out of the box, without changing server\nroutes. Specify EYWA_SERVE environment variables to serve some folder. Folder is\nserved as SPA. Interceptor responsible for serving files will try to find file\nif URL has extension (.js, .css, .html) and if it doesn't find file, interceptor will try\nto find index.html at every level. Like `/level1/level2/level3/level4`\nwill try to serve level4 index.html, then level3 index.html and so on.\n\n\n##### EYWA_IAM_ENFORCE_ACCESS\nEnforcing access is disabled by default. It is \"annoying\" to try something out and\nhack, or develop this project if you have to specify every detail. For this reason\naccess enforcing is disabled by default and if you wan't to use it then set\n`EYWA_IAM_ENFORCE_ACCESS=true`\n\n\n##### Enterprise Environment\nUsually in enterprise environments there are two obstacles that will make EYWA harder to use.\nEnterprises use proxy to control http traffic so make sure to adjust `http_proxy`\nand `https_proxy` environment variables according to enterprise standards.\n\nSecond one is less likely but still occurs. If your enterprise uses internal Certificate Authority(CA)\nfor signing SSL traffic use keytool to add CA to java keystore. Specify\n`TRUST_STORE_PATH` and `TRUST_STORE_PASSWORD` so that eywa can use keystore\nand check if this incoming traffic is signed by trusted certificate.\n\n\nThere are many more environment variables that can be configured. More about that\nlook at official **[documentation](https://neyho.github.io/eywa/docs/overview)**\nspecificaly documentation refering to **[environment](https://neyho.github.io/eywa/docs/advanced/environment)**\n\n\n#### Features\n- [x] - GraphQL Sync Mutation\n- [x] - GraphQL Stack Mutation\n- [x] - GraphQL Slice Mutation\n- [x] - GraphQL Purge Mutation\n- [x] - GraphQL Delete Mutation\n- [x] - GraphQL Sync/Stack List mutation for batch insertion/update \n- [x] - GraphQL Search Query\n- [x] - GraphQL Get Query\n- [x] - GraphQL SearchTree Query for recursive relations\n- [x] - Aggregate fields for Query operations (count, avg, max, min, sum)\n- [x] - Hash attribute type\n- [x] - Encryption attribute type\n- [ ] - Currency attribute type\n- [x] - Enforcing read, write, delete righths through IAM Roles\n- [x] - Extend GraphQL schema with hooks\n- [x] - Extend GraphQL schema fields with resolvers for mutations, queries and subscriptions\n\n\n#### Supported DB\n- [x] - PostgreSQL implementation\n- [ ] - MySQL implementation\n- [ ] - SQLite implementation \n- [ ] - CochroachDB implementation \n- [ ] - Datalevin\n- [ ] - XTDB implementation \n\n\n#### OAuth \u0026 OIDC\n- [x] - Authorization Code flow\n- [x] - Device Code flow\n- [ ] - User Confirmation Page\n- [ ] - MultiFactor authentication\n- [ ] - Passkey authentication\n- [x] - IAM Role Access Management\n- [x] - IAM Client registration\n- [x] - IAM API permission control\n- [ ] - External Identity Providers - module for easy onboarding \n- [ ] - Google Identity Provider\n- [ ] - Github Identity Provider\n- [ ] - AuthO Identity Provider\n- [ ] - Amazon Identity Provider\n- [ ] - AD/LDAP Identity Provider\n- [ ] - Persistent sessions\n- [ ] - Persistent tokens\n- [ ] - Persistent JWKS certificate pairs\n- [ ] - JWKS key rotation\n\n\n#### CLI clients\n- [x] - [JS](https://www.npmjs.com/package/eywa-client)\n- [x] - [Python](https://pypi.org/project/eywa-client/)\n- [x] - [Babashka](https://www.clojars.org/org.neyho/eywa-client)\n- [ ] - GO\n- [ ] - Ruby\n\n\n#### Misc\n- [ ] - Explore module - dynamic visualization\n- [ ] - Documentation\n- [x] - Use cases / [examples](https://github.com/neyho/eywa-examples)\n\n\n\n### Credits\n\nThis project wouldn't be possible without [Lacinia](https://github.com/walmartlabs/lacinia)\nwhich powers backend and [helix](https://github.com/lilactown/helix) \u0026 [shadow-css](https://github.com/thheller/shadow-css)\nwhich power frontend. Many thanks to the people that created these projects as well as all other maintainers and contributors.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fneyho%2Feywa","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fneyho%2Feywa","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fneyho%2Feywa/lists"}