-
Notifications
You must be signed in to change notification settings - Fork 0
feat(keycloak): add OrgMemory login theme #346
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,167 @@ | ||
| --- | ||
| name: openfga | ||
| description: OpenFGA authorization modeling best practices for defining types and relations, writing relationship tuples, deriving can_* permissions, applying type restrictions and usersets, and authoring .fga.yaml check/list_objects/list_users tests. Use when authoring, reviewing, or refactoring OpenFGA models, tuples, permissions, .fga files, .fga.yaml test files, or OpenFGA SDK integrations in JavaScript, TypeScript, Go, Python, Java, or .NET. | ||
| license: Apache-2.0 | ||
| metadata: | ||
| author: openfga | ||
| version: "1.2.1" | ||
| --- | ||
|
|
||
| # OpenFGA Best Practices | ||
|
|
||
| Use this skill to design and review OpenFGA models end to end: define types and relations, write tuples, derive `can_*` permissions, choose usersets and inheritance patterns, and validate behavior with `.fga.yaml` tests and CLI checks. | ||
|
|
||
| ## Quick Start Example | ||
|
|
||
| Minimal model: | ||
|
|
||
| ```fga | ||
| model | ||
| schema 1.1 | ||
|
|
||
| type user | ||
|
|
||
| type organization | ||
| relations | ||
| define admin: [user] | ||
| define member: [user] or admin | ||
|
|
||
| type document | ||
| relations | ||
| define organization: [organization] | ||
| define owner: [user] | ||
| define can_edit: owner or admin from organization | ||
| define can_view: can_edit or member from organization | ||
| ``` | ||
|
|
||
| Example tuples: | ||
|
|
||
| ```text | ||
| organization:acme#admin@user:alice | ||
| document:roadmap#organization@organization:acme | ||
| document:roadmap#owner@user:bob | ||
| ``` | ||
|
|
||
| Example test targets: | ||
| - `check` that `user:alice` can view and edit `document:roadmap` | ||
| - `check` that `user:bob` can edit their own document | ||
| - `list_users` for `document:roadmap#can_view` | ||
| - `list_objects` for documents `user:alice` can edit | ||
|
|
||
| ## How to Use | ||
|
|
||
| When a workflow step points to a rule ID, open the matching file in `references/` for detailed guidance and examples. | ||
|
|
||
| **Note:** SDK references (`sdk-*.md`) are only needed for integration tasks — skip them during pure model authoring and testing. | ||
|
|
||
| ## Rule Index | ||
|
|
||
| ### Core | ||
| | File | Description | | ||
| |------|-------------| | ||
| | `references/core-types.md` | Define types for entity classes | | ||
| | `references/core-relations.md` | Relations belong on object types | | ||
| | `references/core-tuples.md` | Relationship tuples as facts | | ||
| | `references/core-separation.md` | Model vs data separation | | ||
| | `references/core-schema-version.md` | Schema version | | ||
|
|
||
| ### Relations | ||
| | File | Description | | ||
| |------|-------------| | ||
| | `references/relation-direct.md` | Direct relationships | | ||
| | `references/relation-indirect.md` | Indirect relationships with X from Y | | ||
| | `references/relation-concentric.md` | Concentric relationships | | ||
| | `references/relation-usersets.md` | Usersets for group-based access | | ||
| | `references/relation-conditions.md` | Conditional relationships | | ||
| | `references/relation-wildcards.md` | Wildcards for public access | | ||
| | `references/relation-wildcards-as-booleans.md` | Wildcards for boolean attributes | | ||
|
|
||
| ### Design | ||
| | File | Description | | ||
| |------|-------------| | ||
| | `references/design-permissions.md` | Define permissions with can_ relations | | ||
| | `references/design-hierarchy.md` | Hierarchical structures | | ||
| | `references/design-organization.md` | Organization-level access | | ||
| | `references/design-create-on-parent.md` | Check create permissions on parent objects | | ||
| | `references/design-naming.md` | Naming conventions | | ||
| | `references/design-modules.md` | Modularize models (only when asked) | | ||
|
|
||
| ### Roles | ||
| | File | Description | | ||
| |------|-------------| | ||
| | `references/roles-simple.md` | Simple static roles | | ||
| | `references/roles-static-combo.md` | Combining static and custom roles | | ||
| | `references/roles-assignments.md` | Role assignments for resource-specific roles | | ||
| | `references/roles-when-to-use.md` | When to use each role pattern | | ||
|
|
||
| ### Optimization | ||
| | File | Description | | ||
| |------|-------------| | ||
| | `references/optimize-simplify.md` | Simplify models | | ||
| | `references/optimize-tuples.md` | Minimize tuple count | | ||
| | `references/optimize-type-restrictions.md` | Type restrictions | | ||
|
|
||
| ### Testing | ||
| | File | Description | | ||
| |------|-------------| | ||
| | `references/test-fga-yaml.md` | Structure tests in .fga.yaml | | ||
| | `references/test-check-assertions.md` | Check assertions | | ||
| | `references/test-list-objects.md` | List objects tests | | ||
| | `references/test-list-users.md` | List users tests | | ||
| | `references/test-conditions.md` | Testing conditions | | ||
| | `references/test-cli.md` | OpenFGA CLI usage | | ||
| | `references/workflow-validate.md` | Always validate models | | ||
|
|
||
| ### SDKs (for integration tasks only) | ||
| | File | Description | | ||
| |------|-------------| | ||
| | `references/sdk-javascript.md` | JavaScript/TypeScript SDK | | ||
| | `references/sdk-go.md` | Go SDK | | ||
| | `references/sdk-python.md` | Python SDK | | ||
| | `references/sdk-java.md` | Java SDK | | ||
| | `references/sdk-dotnet.md` | .NET SDK | | ||
|
|
||
| ## Recommended Workflow | ||
|
|
||
| 1. Model the resource graph. | ||
| Define types, direct relations, inheritance edges, and `can_*` permissions. | ||
| Rules to check first: `core-*`, `relation-*`, `design-permissions`, `design-hierarchy`. | ||
|
|
||
| 2. Add tuples and test intent. | ||
| Add representative tuples and cover expected behavior with `check`, `list_objects`, and `list_users` tests. | ||
| Rules to check next: `core-tuples`, `test-fga-yaml`, `test-check-assertions`, `test-list-objects`, `test-list-users`. | ||
|
|
||
| 3. Review parent-child creation and deletion paths. | ||
| Verify each parent -> child edge has create permissions on the parent and that no child permission is directly grantable unless intended. | ||
| Rules to check: `design-create-on-parent`, `relation-direct`, `design-permissions`. | ||
|
|
||
| 4. Simplify before removing schema. | ||
| Before deleting any type or relation, confirm it is not referenced by permissions, tuples, or tests. | ||
| If a simplification breaks a reference: restore the relation or update the model/tests, then re-run this step. | ||
| Rules to check: `optimize-simplify`, `optimize-tuples`, `optimize-type-restrictions`. | ||
|
|
||
| 5. Validate the model. | ||
| Run: | ||
|
|
||
| ```bash | ||
| fga model validate --file stores/<store>/model.fga | ||
| ``` | ||
|
|
||
| If validation fails: read the reported relation or type errors, fix the model, and re-run validation before continuing. | ||
|
|
||
| 6. Run the store tests. | ||
| Run: | ||
|
|
||
| ```bash | ||
| fga model test --tests stores/<store>/store.fga.yaml | ||
| ``` | ||
|
|
||
| If tests fail: update tuples, assertions, or permission definitions, then re-run tests until all checks and list queries pass. | ||
|
Comment on lines
+143
to
+159
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win 🧩 Analysis chain🏁 Script executed: #!/bin/bash
set -euo pipefail
echo "== candidate files =="
git ls-files | rg '(^|/)(SKILL\.md|store\.fga\.yaml|model\.fga|README|package\.json|pyproject\.toml|justfile|Makefile)$' | sed -n '1,200p'
echo
echo "== SKILL.md around target lines =="
if [ -f .agents/skills/openfga/SKILL.md ]; then
nl -ba .agents/skills/openfga/SKILL.md | sed -n '120,175p'
else
fd -a 'SKILL\.md$' .agents/skills/openfga -x sh -c 'echo "--- $1"; nl -ba "$1" | sed -n "120,175p"' sh {}
fi
echo
echo "== openfga fixture files =="
git ls-files | rg 'openfga|authorization-openfga' | sed -n '1,200p'
if [ -f integrations/authorization-openfga/src/test/openfga/store.fga.yaml ]; then
echo
echo "== fixture contents =="
nl -ba integrations/authorization-openfga/src/test/openfga/store.fga.yaml | sed -n '1,160p'
fi
echo
echo "== references to stores/ and model commands =="
rg -n '\bstores/|--file=model\.fga|--tests=|--tests|\bopenfga|\bFGA|authorization-openfga' .agents/skills integrations/authorization-openfga README.md 2>/dev/null || true
echo
echo "== static path validation for yaml refs =="
python3 - <<'PY'
from pathlib import Path
p=Path('integrations/authorization-openfga/src/test/openfga/store.fga.yaml')
if p.exists():
text=p.read_text()
print('exists:', p)
for i,line in enumerate(text.splitlines(),1):
if 'stores/' in line or 'model.fga' in line or 'fga' in line:
print(f'{i}: {line}')
PYRepository: kl3inIT/OrgMemory Length of output: 1804 🏁 Script executed: #!/bin/bash
set -euo pipefail
echo "== SKILL.md around target lines =="
python3 - <<'PY'
from pathlib import Path
p = Path('.agents/skills/openfga/SKILL.md')
lines = p.read_text().splitlines()
for i in range(120, min(180, len(lines)) + 1):
print(f'{i}: {lines[i-1]}')
PY
echo
echo "== fixture contents =="
python3 - <<'PY'
from pathlib import Path
p = Path('integrations/authorization-openfga/src/test/openfga/store.fga.yaml')
for i, line in enumerate(p.read_text().splitlines(), 1):
print(f'{i}: {line}')
PY
echo
echo "== model file exists check =="
python3 - <<'PY'
from pathlib import Path
for p in [
Path('integrations/authorization-openfga/src/main/openfga/model.fga'),
Path('integrations/authorization-openfga/src/test/openfga/model.fga'),
]:
print(p, 'exists=', p.exists())
PYRepository: kl3inIT/OrgMemory Length of output: 21213 Make the OpenFGA commands use the repository layout. The repository does not have a 🧰 Tools🪛 markdownlint-cli2 (0.23.2)[warning] 152-152: Ordered list item prefix (MD029, ol-prefix) 🤖 Prompt for AI AgentsSource: Path instructions |
||
|
|
||
| 7. Only then finalize delivery. | ||
| For touched stores, finish only after validation and tests are green. | ||
| Final rule to check: `workflow-validate`. | ||
|
|
||
| ## Full Compiled Document | ||
|
|
||
| For the complete guide with all rules expanded: `AGENTS.md` | ||
| Original file line number | Diff line number | Diff line change | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -26,14 +26,17 @@ Select the relevant layered gates from `docs/guidelines/testing-harness.md`. | |||||||||
| For changes spanning ingestion, publication, persistence, worker wiring, or the | ||||||||||
| frontend contract, run at least: | ||||||||||
|
|
||||||||||
| ```powershell | ||||||||||
| .\gradlew.bat --no-daemon :core:test :apps:api:test :apps:worker:test | ||||||||||
| .\gradlew.bat --no-daemon clean test | ||||||||||
| ```bash | ||||||||||
| ./gradlew --no-daemon :core:test :apps:api:test :apps:worker:test | ||||||||||
| ./gradlew --no-daemon clean test | ||||||||||
| corepack pnpm --filter @orgmemory/web typecheck | ||||||||||
| corepack pnpm --filter @orgmemory/web test:unit | ||||||||||
| corepack pnpm --filter @orgmemory/web build | ||||||||||
| ``` | ||||||||||
|
|
||||||||||
| On native Windows replace `./gradlew` with `gradlew.bat`; the Corepack commands | ||||||||||
| are unchanged. | ||||||||||
|
|
||||||||||
| The terminating `clean test` command is the Spring context gate. Never use | ||||||||||
| `bootRun` as verification because it does not terminate on success. | ||||||||||
|
|
||||||||||
|
|
@@ -44,7 +47,8 @@ When a REST endpoint or DTO changes, the committed contracts under | |||||||||
| `apps/api/.../OpenApiContractTests.java`): | ||||||||||
|
|
||||||||||
| 1. Refresh: set `ORGMEMORY_OPENAPI_WRITE=true` and run | ||||||||||
| `.\gradlew.bat :apps:api:test --tests "*OpenApiContractTests*"`. | ||||||||||
| `./gradlew :apps:api:test --tests '*OpenApiContractTests*'`. | ||||||||||
| On native Windows use `gradlew.bat` in place of `./gradlew`. | ||||||||||
|
Comment on lines
+50
to
+51
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win Use shell-neutral quoting for the Gradle test filter. The command uses single quotes around Proposed fix- `./gradlew :apps:api:test --tests '*OpenApiContractTests*'`.
+ `./gradlew :apps:api:test --tests "*OpenApiContractTests*"`.📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||
| 2. Regenerate the browser client: | ||||||||||
| `corepack pnpm --filter @orgmemory/web gen:api` — the hey-api output is | ||||||||||
| gitignored, so it is regenerated, never committed. | ||||||||||
|
|
||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win
Resolve the reported Markdown lint and labeling defects.
.agents/skills/openfga/SKILL.md#L59-L116: add blank lines around the rule-index headings and tables..agents/skills/openfga/SKILL.md#L152-L161: use the configured ordered-list prefix style..agents/skills/openfga/references/relation-concentric.md#L83-L83: label the fenced diagram astext..agents/skills/openfga/references/relation-wildcards-as-booleans.md#L5-L22: rename the heading to match the boolean-attribute topic and change**Tuples **to**Tuples**.🧰 Tools
🪛 markdownlint-cli2 (0.23.2)
[warning] 59-59: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
[warning] 60-60: Tables should be surrounded by blank lines
(MD058, blanks-around-tables)
[warning] 68-68: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
[warning] 69-69: Tables should be surrounded by blank lines
(MD058, blanks-around-tables)
[warning] 79-79: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
[warning] 80-80: Tables should be surrounded by blank lines
(MD058, blanks-around-tables)
[warning] 89-89: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
[warning] 90-90: Tables should be surrounded by blank lines
(MD058, blanks-around-tables)
[warning] 97-97: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
[warning] 98-98: Tables should be surrounded by blank lines
(MD058, blanks-around-tables)
[warning] 104-104: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
[warning] 105-105: Tables should be surrounded by blank lines
(MD058, blanks-around-tables)
[warning] 115-115: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
[warning] 116-116: Tables should be surrounded by blank lines
(MD058, blanks-around-tables)
📍 Affects 3 files
.agents/skills/openfga/SKILL.md#L59-L116(this comment).agents/skills/openfga/SKILL.md#L152-L161.agents/skills/openfga/references/relation-concentric.md#L83-L83.agents/skills/openfga/references/relation-wildcards-as-booleans.md#L5-L22🤖 Prompt for AI Agents
Source: Linters/SAST tools