Skip to content

Conversation

@SafinWasi
Copy link
Contributor

@SafinWasi SafinWasi commented Dec 22, 2025

Must be merged after JanssenProject/jans#12833

Summary by CodeRabbit

  • New Features

    • Added 17+ new access control policies covering read, write, execute, search, compare, monitor, tag, and share operations across multiple roles.
    • Implemented conditional access controls based on network type, geolocation, device health, email domain, and fraud indicators.
  • Updates

    • Refined existing policy with more specific resource type constraints.
    • Expanded trusted issuer configuration and schema definitions for enhanced token metadata handling.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link

coderabbitai bot commented Dec 22, 2025

📝 Walkthrough

Walkthrough

This PR introduces 17 new access control policy definitions and modifies 1 existing policy within a policy management system. Two configuration JSON files are updated to register the new policies, expand trusted issuer metadata, and enhance token metadata structures with user tracking and role-based principal mappings.

Changes

Cohort / File(s) Summary
JSON Configuration Files
449805c83e13f332b1b35eac6ffa93187fbd1c648085.json
Updated existing policy allow_teacher to allow_teacher_secretdocument with refined policy content. Added 17 new policy entries across various permission scenarios (read, write, execute, monitor, search, tag, compare, share). Expanded trusted_issuers with new issuer key and enriched token_metadata fields (user_id, token_id, workload_id, role_mapping, claim_mapping, principal_mapping). Replaced schema field with expanded payload.
JSON Schema Update
6d9f73b2d44ad4e7aa8f1182cde9f72dcbaa244f4327.json
Updated schema field with new base64-encoded content; all other fields remain unchanged.
Policy Rule Files (Permit Rules)
tarpDemo/91b2611a1ea9859cb7ce780ca16adf3b2a68f892786a.policy, tarpDemo/6e46e36071466cc37c0e9bbd65f16c51ea2ab152c6fc.policy, tarpDemo/e76eb1853f0c6a199ca383cd9714e0113dfd851e079a.policy, tarpDemo/b5111ecf0d218da2cdbece83aeb77cb6b479d3b5d85c.policy, tarpDemo/c4729e4ab456b4c8e74102593e5b32e04176bc837cc5.policy, tarpDemo/4ab79a92feac06a1a005373b741ed50e07d23d98f9a5.policy, tarpDemo/13b34711a196f382ade96677cefd513a2a6deff1b949.policy, tarpDemo/fe84f983188f1639a03ed77c0753fc893fbe0d4cf155.policy, tarpDemo/9e2f1520bd292765609e8ce57add8d3c134e3a91759d.policy, tarpDemo/e459eba6691d141497dd1317e44d3d5b3bdd9fd65150.policy, tarpDemo/50c0ea31a9ed25a575b7538dec38cb953431651e7bec.policy
New permit-based access control policies enabling various actions: user_can_read, user_can_search, user_can_execute, user_can_monitor, user_can_compare, user_can_tag, admin_can_write_to_application, editor_can_share, security_admin_can_write_to_secretdocument, user_can_read_if_confidential_role, user_can_read_if_email_is_example.
Policy Rule Files (Forbid Rules)
tarpDemo/28e83add6e203af0d3814f06228e45a0eeb5c1269b08.policy, tarpDemo/420184da127304d1b2898761893a974096f6dbade45a.policy, tarpDemo/689edd369c276afb5a163119dcd92c74196a4e0c7bdb.policy, tarpDemo/c367d06f19af8db1ec69354044334c799ff4cd2021ae.policy, tarpDemo/f38f10e80c6f429153cf97781a4c6bcf29761a04259f.policy, tarpDemo/fe83e4b2338614b970559ce4141b6d3e60559d79282c.policy, tarpDemo/870eaec25d9c8e9a642c4ed4d08b1ad480e6bc1348c7.policy
New forbid-based access control policies restricting actions based on contextual conditions: user_cannot_write_from_restricted_country (geolocation), user_cannot_execute_on_public_network (network type), user_cannot_read_if_compromised (device health), user_cannot_read_if_fraudulent (fraud indicators), cannot_write_if_not_admin (role check), user_can_read_in_corp_network (network context), user_cannot_write_to_secretdocument.
Updated Policy Rule
tarpDemo/76acfe86fb09731682f92c4fbf7d2e066813ce639404.policy
Policy identifier updated from allow_teacher to allow_teacher_secretdocument. Resource constraint refined from bare resource reference to typed constraint resource is Jans::SecretDocument.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Pre-merge checks and finishing touches

❌ Failed checks (1 inconclusive)
Check name Status Explanation Resolution
Title check ❓ Inconclusive The title 'refactor: new policies' is vague and overly generic. It mentions 'refactor' but the changes are primarily feature additions (16+ new policy files), not refactoring. The term 'new policies' is too broad to convey meaningful detail about what was changed. Consider a more specific title such as 'feat: add access control policies for demo' or 'feat: add 16 TARP policies with context and role-based rules' to better describe the actual change.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@ossdhaval
Copy link
Contributor

Hi @SafinWasi

Policies add much needed variety of examples to the demo 👍

Before merging, you'll need to take care of Unverified commits and DCO.

@SafinWasi SafinWasi marked this pull request as ready for review December 29, 2025 02:24
@SafinWasi
Copy link
Contributor Author

@ossdhaval unfortunately commits authored under Agama Lab are not GPG signed as that functionality is beyond the capacities of github app installation.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 13

📜 Review details

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 75507b5 and 75a1bfd.

📒 Files selected for processing (21)
  • 449805c83e13f332b1b35eac6ffa93187fbd1c648085.json
  • 6d9f73b2d44ad4e7aa8f1182cde9f72dcbaa244f4327.json
  • tarpDemo/13b34711a196f382ade96677cefd513a2a6deff1b949.policy
  • tarpDemo/28e83add6e203af0d3814f06228e45a0eeb5c1269b08.policy
  • tarpDemo/420184da127304d1b2898761893a974096f6dbade45a.policy
  • tarpDemo/4ab79a92feac06a1a005373b741ed50e07d23d98f9a5.policy
  • tarpDemo/50c0ea31a9ed25a575b7538dec38cb953431651e7bec.policy
  • tarpDemo/689edd369c276afb5a163119dcd92c74196a4e0c7bdb.policy
  • tarpDemo/6e46e36071466cc37c0e9bbd65f16c51ea2ab152c6fc.policy
  • tarpDemo/76acfe86fb09731682f92c4fbf7d2e066813ce639404.policy
  • tarpDemo/870eaec25d9c8e9a642c4ed4d08b1ad480e6bc1348c7.policy
  • tarpDemo/91b2611a1ea9859cb7ce780ca16adf3b2a68f892786a.policy
  • tarpDemo/9e2f1520bd292765609e8ce57add8d3c134e3a91759d.policy
  • tarpDemo/b5111ecf0d218da2cdbece83aeb77cb6b479d3b5d85c.policy
  • tarpDemo/c367d06f19af8db1ec69354044334c799ff4cd2021ae.policy
  • tarpDemo/c4729e4ab456b4c8e74102593e5b32e04176bc837cc5.policy
  • tarpDemo/e459eba6691d141497dd1317e44d3d5b3bdd9fd65150.policy
  • tarpDemo/e76eb1853f0c6a199ca383cd9714e0113dfd851e079a.policy
  • tarpDemo/f38f10e80c6f429153cf97781a4c6bcf29761a04259f.policy
  • tarpDemo/fe83e4b2338614b970559ce4141b6d3e60559d79282c.policy
  • tarpDemo/fe84f983188f1639a03ed77c0753fc893fbe0d4cf155.policy
🔇 Additional comments (15)
tarpDemo/c4729e4ab456b4c8e74102593e5b32e04176bc837cc5.policy (1)

1-6: LGTM! Simple and well-structured policy.

The policy correctly defines a permit rule allowing users to perform Compare actions on applications. The Cedar syntax is correct and the policy logic is straightforward.

tarpDemo/e459eba6691d141497dd1317e44d3d5b3bdd9fd65150.policy (1)

1-6: Sensitive resource access granted - verify role assignment process.

This policy grants read access to SecretDocument for users in the "confidential" role. Ensure that the assignment of users to the "confidential" role is properly controlled and audited, as this grants access to sensitive documents.

tarpDemo/4ab79a92feac06a1a005373b741ed50e07d23d98f9a5.policy (1)

1-6: LGTM! Clean policy definition.

The policy correctly defines a permit rule for users to tag applications. The syntax is correct and the logic is clear.

tarpDemo/91b2611a1ea9859cb7ce780ca16adf3b2a68f892786a.policy (1)

1-6: Broad permission granted - verify this aligns with security requirements.

This policy allows all users to read applications without any conditions. Ensure this level of access is intended and aligns with the principle of least privilege for your security model.

tarpDemo/c367d06f19af8db1ec69354044334c799ff4cd2021ae.policy (1)

1-9: Good security practice with explicit deny rule.

This forbid policy correctly implements fraud-based access denial. The syntax properly checks for the existence of fraud_indicators before accessing it. In Cedar, forbid policies take precedence over permit policies, ensuring that fraudulent requests are blocked even if other policies would permit access.

Verify that the "high_risk" string value matches the fraud indicator values set by your backend application when populating the request context.

tarpDemo/fe84f983188f1639a03ed77c0753fc893fbe0d4cf155.policy (1)

3-3: Standardize role naming conventions across policies.

This policy uses capitalized role name "Editor", but other policies use inconsistent conventions: "confidential", "admin", and "security-admin" (lowercase), while "Teacher" and "Student" are capitalized. Apply a consistent naming convention (all lowercase or all capitalized) across all role definitions to prevent runtime authorization mismatches.

tarpDemo/fe83e4b2338614b970559ce4141b6d3e60559d79282c.policy (1)

6-9: Context attribute population and security validation are outside the scope of this policy file and must be verified at the enforcement point level.

This policy's defensive check (context has network &&) is sound, but the three underlying concerns cannot be verified within this quickstart repository because it contains only policy definitions and schema. The enforcement point implementation—which is responsible for populating context attributes, ensuring network classification security, and validating the "corp" designation—is not included in this repository. These validations need to be confirmed in the Cedarling framework or the consuming application.

6d9f73b2d44ad4e7aa8f1182cde9f72dcbaa244f4327.json (1)

15-15: Schema includes all required types and properly supports new policies and actions.

Verification confirms all components are correctly defined:

  1. All new actions (Compare, Share, Tag, Monitor, DELETE, Execute, GET, HEAD, PATCH, POST, PUT, Read, Search, Write) are present with proper appliesTo definitions
  2. Resource types Application and SecretDocument are properly defined; Application includes attributes (app_id, name, url)
  3. Context attributes required for conditional policies are all defined: current_time, device_health, fraud_indicators, geolocation, network, network_type, operating_system, tokens, user_agent
  4. Role entity type is properly included and referenced
tarpDemo/76acfe86fb09731682f92c4fbf7d2e066813ce639404.policy (1)

5-5: Breaking change: Resource constraint narrowed to SecretDocument.

The resource constraint changed from a generic resource to resource is Jans::SecretDocument, which significantly narrows the policy scope. Verify that this is intentional and that Teacher role access to other resource types (if needed) is covered by other policies.

tarpDemo/9e2f1520bd292765609e8ce57add8d3c134e3a91759d.policy (1)

1-6: LGTM!

The policy correctly grants write access to SecretDocument resources only to principals in the security-admin role. The syntax and logic are sound.

tarpDemo/6e46e36071466cc37c0e9bbd65f16c51ea2ab152c6fc.policy (1)

1-6: LGTM!

The policy correctly permits any Jans::User entity to perform the Search action on Application resources. The syntax is valid Cedar.

tarpDemo/50c0ea31a9ed25a575b7538dec38cb953431651e7bec.policy (1)

1-10: LGTM!

The policy demonstrates proper attribute-based access control with Cedar. The when clause correctly guards against missing attributes by checking principal has email before accessing principal.email.domain.

tarpDemo/13b34711a196f382ade96677cefd513a2a6deff1b949.policy (1)

1-6: LGTM!

The policy correctly grants write access to Application resources for principals in the admin role. Syntax and logic are correct.

449805c83e13f332b1b35eac6ffa93187fbd1c648085.json (2)

7-102: Policy registry looks consistent with policy files.

The policy entries correctly register all new policies with appropriate descriptions. The base64-encoded policy_content fields match the corresponding .policy files in the tarpDemo/ directory.


152-157: Verify tx_token configuration completeness.

The tx_token configuration is missing several fields that are present in other token types: required_claims, role_mapping, claim_mapping, and principal_mapping. If transaction tokens will be used for authorization decisions, this incomplete configuration may cause runtime issues.

Is this intentional, or should tx_token have the same metadata fields as the other token types?

Comment on lines +105 to 108
"1985d6d8767b87d752035c9f9c0078daf057ad2cd5ea": {
"name": "Jans",
"description": "testIdp",
"description": "",
"openid_configuration_endpoint": "https://test-jans.gluu.info/.well-known/openid-configuration",
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial

Consider adding a description for the trusted issuer.

The description field is empty. Adding a brief description would improve documentation and help maintainers understand the purpose of this issuer configuration.

🤖 Prompt for AI Agents
In 449805c83e13f332b1b35eac6ffa93187fbd1c648085.json around lines 105–108 the
trusted issuer entry with id "1985d6d8767b87d752035c9f9c0078daf057ad2cd5ea" has
an empty "description" field; add a concise, one-sentence description that
explains the issuer's purpose (e.g., environment, owner, or service it
represents) so maintainers understand why this issuer exists and any special
context.

}
},
"schema": "eyJKYW5zIjp7ImNvbW1vblR5cGVzIjp7IkNvbnRleHQiOnsidHlwZSI6IlJlY29yZCIsImF0dHJpYnV0ZXMiOnsiY3VycmVudF90aW1lIjp7InR5cGUiOiJFbnRpdHlPckNvbW1vbiIsInJlcXVpcmVkIjpmYWxzZSwibmFtZSI6IkxvbmcifSwiZGV2aWNlX2hlYWx0aCI6eyJ0eXBlIjoiU2V0IiwicmVxdWlyZWQiOmZhbHNlLCJlbGVtZW50Ijp7InR5cGUiOiJFbnRpdHlPckNvbW1vbiIsIm5hbWUiOiJTdHJpbmcifX0sImZyYXVkX2luZGljYXRvcnMiOnsidHlwZSI6IlNldCIsInJlcXVpcmVkIjpmYWxzZSwiZWxlbWVudCI6eyJ0eXBlIjoiRW50aXR5T3JDb21tb24iLCJuYW1lIjoiU3RyaW5nIn19LCJnZW9sb2NhdGlvbiI6eyJ0eXBlIjoiU2V0IiwicmVxdWlyZWQiOmZhbHNlLCJlbGVtZW50Ijp7InR5cGUiOiJFbnRpdHlPckNvbW1vbiIsIm5hbWUiOiJTdHJpbmcifX0sIm5ldHdvcmsiOnsidHlwZSI6IkVudGl0eU9yQ29tbW9uIiwicmVxdWlyZWQiOmZhbHNlLCJuYW1lIjoiU3RyaW5nIn0sIm5ldHdvcmtfdHlwZSI6eyJ0eXBlIjoiRW50aXR5T3JDb21tb24iLCJyZXF1aXJlZCI6ZmFsc2UsIm5hbWUiOiJTdHJpbmcifSwib3BlcmF0aW5nX3N5c3RlbSI6eyJ0eXBlIjoiRW50aXR5T3JDb21tb24iLCJyZXF1aXJlZCI6ZmFsc2UsIm5hbWUiOiJTdHJpbmcifSwidXNlcl9hZ2VudCI6eyJ0eXBlIjoiRW50aXR5T3JDb21tb24iLCJyZXF1aXJlZCI6ZmFsc2UsIm5hbWUiOiJTdHJpbmcifX19LCJlbWFpbF9hZGRyZXNzIjp7InR5cGUiOiJSZWNvcmQiLCJhdHRyaWJ1dGVzIjp7ImRvbWFpbiI6eyJ0eXBlIjoiRW50aXR5T3JDb21tb24iLCJuYW1lIjoiU3RyaW5nIn0sInVpZCI6eyJ0eXBlIjoiRW50aXR5T3JDb21tb24iLCJuYW1lIjoiU3RyaW5nIn19fSwiVXJsIjp7InR5cGUiOiJSZWNvcmQiLCJhdHRyaWJ1dGVzIjp7Imhvc3QiOnsidHlwZSI6IkVudGl0eU9yQ29tbW9uIiwibmFtZSI6IlN0cmluZyJ9LCJwYXRoIjp7InR5cGUiOiJFbnRpdHlPckNvbW1vbiIsIm5hbWUiOiJTdHJpbmcifSwicHJvdG9jb2wiOnsidHlwZSI6IkVudGl0eU9yQ29tbW9uIiwibmFtZSI6IlN0cmluZyJ9fX19LCJlbnRpdHlUeXBlcyI6eyJBY2Nlc3NfdG9rZW4iOnsic2hhcGUiOnsidHlwZSI6IlJlY29yZCIsImF0dHJpYnV0ZXMiOnsiYXVkIjp7InR5cGUiOiJFbnRpdHlPckNvbW1vbiIsIm5hbWUiOiJTdHJpbmcifSwiZXhwIjp7InR5cGUiOiJFbnRpdHlPckNvbW1vbiIsIm5hbWUiOiJMb25nIn0sImlhdCI6eyJ0eXBlIjoiRW50aXR5T3JDb21tb24iLCJuYW1lIjoiTG9uZyJ9LCJpc3MiOnsidHlwZSI6IkVudGl0eU9yQ29tbW9uIiwibmFtZSI6IlRydXN0ZWRJc3N1ZXIifSwianRpIjp7InR5cGUiOiJFbnRpdHlPckNvbW1vbiIsInJlcXVpcmVkIjpmYWxzZSwibmFtZSI6IlN0cmluZyJ9LCJuYmYiOnsidHlwZSI6IkVudGl0eU9yQ29tbW9uIiwicmVxdWlyZWQiOmZhbHNlLCJuYW1lIjoiTG9uZyJ9LCJzY29wZSI6eyJ0eXBlIjoiU2V0IiwicmVxdWlyZWQiOmZhbHNlLCJlbGVtZW50Ijp7InR5cGUiOiJFbnRpdHlPckNvbW1vbiIsIm5hbWUiOiJTdHJpbmcifX19fX0sIkFwcGxpY2F0aW9uIjp7InNoYXBlIjp7InR5cGUiOiJSZWNvcmQiLCJhdHRyaWJ1dGVzIjp7ImFwcF9pZCI6eyJ0eXBlIjoiRW50aXR5T3JDb21tb24iLCJuYW1lIjoiU3RyaW5nIn0sIm5hbWUiOnsidHlwZSI6IkVudGl0eU9yQ29tbW9uIiwibmFtZSI6IlN0cmluZyJ9LCJ1cmwiOnsidHlwZSI6IkVudGl0eU9yQ29tbW9uIiwibmFtZSI6IlVybCJ9fX19LCJIVFRQX1JlcXVlc3QiOnsic2hhcGUiOnsidHlwZSI6IlJlY29yZCIsImF0dHJpYnV0ZXMiOnsiaGVhZGVyIjp7InR5cGUiOiJSZWNvcmQiLCJhdHRyaWJ1dGVzIjp7IkFjY2VwdCI6eyJ0eXBlIjoiRW50aXR5T3JDb21tb24iLCJyZXF1aXJlZCI6ZmFsc2UsIm5hbWUiOiJTdHJpbmcifX19LCJ1cmwiOnsidHlwZSI6IkVudGl0eU9yQ29tbW9uIiwibmFtZSI6IlVybCJ9fX19LCJpZF90b2tlbiI6eyJzaGFwZSI6eyJ0eXBlIjoiUmVjb3JkIiwiYXR0cmlidXRlcyI6eyJhY3IiOnsidHlwZSI6IkVudGl0eU9yQ29tbW9uIiwicmVxdWlyZWQiOmZhbHNlLCJuYW1lIjoiU3RyaW5nIn0sImFtciI6eyJ0eXBlIjoiU2V0IiwicmVxdWlyZWQiOmZhbHNlLCJlbGVtZW50Ijp7InR5cGUiOiJFbnRpdHlPckNvbW1vbiIsIm5hbWUiOiJTdHJpbmcifX0sImF1ZCI6eyJ0eXBlIjoiU2V0IiwiZWxlbWVudCI6eyJ0eXBlIjoiRW50aXR5T3JDb21tb24iLCJuYW1lIjoiU3RyaW5nIn19LCJhenAiOnsidHlwZSI6IkVudGl0eU9yQ29tbW9uIiwicmVxdWlyZWQiOmZhbHNlLCJuYW1lIjoiU3RyaW5nIn0sImJpcnRoZGF0ZSI6eyJ0eXBlIjoiRW50aXR5T3JDb21tb24iLCJyZXF1aXJlZCI6ZmFsc2UsIm5hbWUiOiJTdHJpbmcifSwiZW1haWwiOnsidHlwZSI6IkVudGl0eU9yQ29tbW9uIiwicmVxdWlyZWQiOmZhbHNlLCJuYW1lIjoiZW1haWxfYWRkcmVzcyJ9LCJleHAiOnsidHlwZSI6IkVudGl0eU9yQ29tbW9uIiwibmFtZSI6IkxvbmcifSwiaWF0Ijp7InR5cGUiOiJFbnRpdHlPckNvbW1vbiIsIm5hbWUiOiJMb25nIn0sImlzcyI6eyJ0eXBlIjoiRW50aXR5T3JDb21tb24iLCJuYW1lIjoiVHJ1c3RlZElzc3VlciJ9LCJqdGkiOnsidHlwZSI6IkVudGl0eU9yQ29tbW9uIiwicmVxdWlyZWQiOmZhbHNlLCJuYW1lIjoiU3RyaW5nIn0sIm5hbWUiOnsidHlwZSI6IkVudGl0eU9yQ29tbW9uIiwicmVxdWlyZWQiOmZhbHNlLCJuYW1lIjoiU3RyaW5nIn0sInBob25lX251bWJlciI6eyJ0eXBlIjoiRW50aXR5T3JDb21tb24iLCJyZXF1aXJlZCI6ZmFsc2UsIm5hbWUiOiJTdHJpbmcifSwicm9sZSI6eyJ0eXBlIjoiU2V0IiwicmVxdWlyZWQiOmZhbHNlLCJlbGVtZW50Ijp7InR5cGUiOiJFbnRpdHlPckNvbW1vbiIsIm5hbWUiOiJTdHJpbmcifX0sInN1YiI6eyJ0eXBlIjoiRW50aXR5T3JDb21tb24iLCJuYW1lIjoiU3RyaW5nIn19fX0sIlJvbGUiOnsic2hhcGUiOnsidHlwZSI6IlJlY29yZCIsImF0dHJpYnV0ZXMiOnt9fX0sIlNlY3JldERvY3VtZW50Ijp7InNoYXBlIjp7InR5cGUiOiJSZWNvcmQiLCJhdHRyaWJ1dGVzIjp7fX19LCJUcnVzdGVkSXNzdWVyIjp7InNoYXBlIjp7InR5cGUiOiJSZWNvcmQiLCJhdHRyaWJ1dGVzIjp7Imlzc3Vlcl9lbnRpdHlfaWQiOnsidHlwZSI6IkVudGl0eU9yQ29tbW9uIiwibmFtZSI6IlVybCJ9fX19LCJVc2VyIjp7InNoYXBlIjp7InR5cGUiOiJSZWNvcmQiLCJhdHRyaWJ1dGVzIjp7ImVtYWlsIjp7InR5cGUiOiJFbnRpdHlPckNvbW1vbiIsInJlcXVpcmVkIjpmYWxzZSwibmFtZSI6ImVtYWlsX2FkZHJlc3MifSwiaWRfdG9rZW4iOnsidHlwZSI6IkVudGl0eU9yQ29tbW9uIiwicmVxdWlyZWQiOmZhbHNlLCJuYW1lIjoiaWRfdG9rZW4ifSwicGhvbmVfbnVtYmVyIjp7InR5cGUiOiJFbnRpdHlPckNvbW1vbiIsInJlcXVpcmVkIjpmYWxzZSwibmFtZSI6IlN0cmluZyJ9LCJyb2xlIjp7InR5cGUiOiJTZXQiLCJlbGVtZW50Ijp7InR5cGUiOiJFbnRpdHlPckNvbW1vbiIsIm5hbWUiOiJTdHJpbmcifX0sInN1YiI6eyJ0eXBlIjoiRW50aXR5T3JDb21tb24iLCJuYW1lIjoiU3RyaW5nIn0sInVzZXJpbmZvX3Rva2VuIjp7InR5cGUiOiJFbnRpdHlPckNvbW1vbiIsInJlcXVpcmVkIjpmYWxzZSwibmFtZSI6IlVzZXJpbmZvX3Rva2VuIn0sInVzZXJuYW1lIjp7InR5cGUiOiJFbnRpdHlPckNvbW1vbiIsInJlcXVpcmVkIjpmYWxzZSwibmFtZSI6IlN0cmluZyJ9fX0sIm1lbWJlck9mVHlwZXMiOlsiUm9sZSJdfSwiVXNlcmluZm9fdG9rZW4iOnsic2hhcGUiOnsidHlwZSI6IlJlY29yZCIsImF0dHJpYnV0ZXMiOnsiYXVkIjp7InR5cGUiOiJFbnRpdHlPckNvbW1vbiIsIm5hbWUiOiJTdHJpbmcifSwiYmlydGhkYXRlIjp7InR5cGUiOiJFbnRpdHlPckNvbW1vbiIsInJlcXVpcmVkIjpmYWxzZSwibmFtZSI6IlN0cmluZyJ9LCJlbWFpbCI6eyJ0eXBlIjoiRW50aXR5T3JDb21tb24iLCJyZXF1aXJlZCI6ZmFsc2UsIm5hbWUiOiJlbWFpbF9hZGRyZXNzIn0sImV4cCI6eyJ0eXBlIjoiRW50aXR5T3JDb21tb24iLCJyZXF1aXJlZCI6ZmFsc2UsIm5hbWUiOiJMb25nIn0sImlhdCI6eyJ0eXBlIjoiRW50aXR5T3JDb21tb24iLCJyZXF1aXJlZCI6ZmFsc2UsIm5hbWUiOiJMb25nIn0sImlzcyI6eyJ0eXBlIjoiRW50aXR5T3JDb21tb24iLCJuYW1lIjoiVHJ1c3RlZElzc3VlciJ9LCJqdGkiOnsidHlwZSI6IkVudGl0eU9yQ29tbW9uIiwicmVxdWlyZWQiOmZhbHNlLCJuYW1lIjoiU3RyaW5nIn0sIm5hbWUiOnsidHlwZSI6IkVudGl0eU9yQ29tbW9uIiwicmVxdWlyZWQiOmZhbHNlLCJuYW1lIjoiU3RyaW5nIn0sInBob25lX251bWJlciI6eyJ0eXBlIjoiRW50aXR5T3JDb21tb24iLCJyZXF1aXJlZCI6ZmFsc2UsIm5hbWUiOiJTdHJpbmcifSwicm9sZSI6eyJ0eXBlIjoiU2V0IiwicmVxdWlyZWQiOmZhbHNlLCJlbGVtZW50Ijp7InR5cGUiOiJFbnRpdHlPckNvbW1vbiIsIm5hbWUiOiJTdHJpbmcifX0sInN1YiI6eyJ0eXBlIjoiRW50aXR5T3JDb21tb24iLCJuYW1lIjoiU3RyaW5nIn19fX0sIldvcmtsb2FkIjp7InNoYXBlIjp7InR5cGUiOiJSZWNvcmQiLCJhdHRyaWJ1dGVzIjp7ImFjY2Vzc190b2tlbiI6eyJ0eXBlIjoiRW50aXR5T3JDb21tb24iLCJyZXF1aXJlZCI6ZmFsc2UsIm5hbWUiOiJBY2Nlc3NfdG9rZW4ifSwiY2xpZW50X2lkIjp7InR5cGUiOiJFbnRpdHlPckNvbW1vbiIsIm5hbWUiOiJTdHJpbmcifSwiaXNzIjp7InR5cGUiOiJFbnRpdHlPckNvbW1vbiIsIm5hbWUiOiJUcnVzdGVkSXNzdWVyIn0sIm5hbWUiOnsidHlwZSI6IkVudGl0eU9yQ29tbW9uIiwicmVxdWlyZWQiOmZhbHNlLCJuYW1lIjoiU3RyaW5nIn0sInJwX2lkIjp7InR5cGUiOiJFbnRpdHlPckNvbW1vbiIsInJlcXVpcmVkIjpmYWxzZSwibmFtZSI6IlN0cmluZyJ9LCJzcGlmZmVfaWQiOnsidHlwZSI6IkVudGl0eU9yQ29tbW9uIiwicmVxdWlyZWQiOmZhbHNlLCJuYW1lIjoiU3RyaW5nIn19fX19LCJhY3Rpb25zIjp7IkNvbXBhcmUiOnsiYXBwbGllc1RvIjp7InByaW5jaXBhbFR5cGVzIjpbIlVzZXIiLCJXb3JrbG9hZCJdLCJyZXNvdXJjZVR5cGVzIjpbIkFwcGxpY2F0aW9uIl0sImNvbnRleHQiOnsidHlwZSI6IkNvbnRleHQifX19LCJERUxFVEUiOnsiYXBwbGllc1RvIjp7InByaW5jaXBhbFR5cGVzIjpbIldvcmtsb2FkIl0sInJlc291cmNlVHlwZXMiOlsiSFRUUF9SZXF1ZXN0Il0sImNvbnRleHQiOnsidHlwZSI6IkNvbnRleHQifX19LCJFeGVjdXRlIjp7ImFwcGxpZXNUbyI6eyJwcmluY2lwYWxUeXBlcyI6WyJVc2VyIiwiV29ya2xvYWQiXSwicmVzb3VyY2VUeXBlcyI6WyJBcHBsaWNhdGlvbiJdLCJjb250ZXh0Ijp7InR5cGUiOiJDb250ZXh0In19fSwiR0VUIjp7ImFwcGxpZXNUbyI6eyJwcmluY2lwYWxUeXBlcyI6WyJXb3JrbG9hZCJdLCJyZXNvdXJjZVR5cGVzIjpbIkhUVFBfUmVxdWVzdCJdLCJjb250ZXh0Ijp7InR5cGUiOiJDb250ZXh0In19fSwiSEVBRCI6eyJhcHBsaWVzVG8iOnsicHJpbmNpcGFsVHlwZXMiOlsiV29ya2xvYWQiXSwicmVzb3VyY2VUeXBlcyI6WyJIVFRQX1JlcXVlc3QiXSwiY29udGV4dCI6eyJ0eXBlIjoiQ29udGV4dCJ9fX0sIk1vbml0b3IiOnsiYXBwbGllc1RvIjp7InByaW5jaXBhbFR5cGVzIjpbIlVzZXIiLCJXb3JrbG9hZCJdLCJyZXNvdXJjZVR5cGVzIjpbIkFwcGxpY2F0aW9uIl0sImNvbnRleHQiOnsidHlwZSI6IkNvbnRleHQifX19LCJQQVRDSCI6eyJhcHBsaWVzVG8iOnsicHJpbmNpcGFsVHlwZXMiOlsiV29ya2xvYWQiXSwicmVzb3VyY2VUeXBlcyI6WyJIVFRQX1JlcXVlc3QiXSwiY29udGV4dCI6eyJ0eXBlIjoiQ29udGV4dCJ9fX0sIlBPU1QiOnsiYXBwbGllc1RvIjp7InByaW5jaXBhbFR5cGVzIjpbIldvcmtsb2FkIl0sInJlc291cmNlVHlwZXMiOlsiSFRUUF9SZXF1ZXN0Il0sImNvbnRleHQiOnsidHlwZSI6IkNvbnRleHQifX19LCJQVVQiOnsiYXBwbGllc1RvIjp7InByaW5jaXBhbFR5cGVzIjpbIldvcmtsb2FkIl0sInJlc291cmNlVHlwZXMiOlsiSFRUUF9SZXF1ZXN0Il0sImNvbnRleHQiOnsidHlwZSI6IkNvbnRleHQifX19LCJSZWFkIjp7ImFwcGxpZXNUbyI6eyJwcmluY2lwYWxUeXBlcyI6WyJVc2VyIiwiV29ya2xvYWQiXSwicmVzb3VyY2VUeXBlcyI6WyJBcHBsaWNhdGlvbiIsIlNlY3JldERvY3VtZW50Il0sImNvbnRleHQiOnsidHlwZSI6IkNvbnRleHQifX19LCJTZWFyY2giOnsiYXBwbGllc1RvIjp7InByaW5jaXBhbFR5cGVzIjpbIlVzZXIiLCJXb3JrbG9hZCJdLCJyZXNvdXJjZVR5cGVzIjpbIkFwcGxpY2F0aW9uIl0sImNvbnRleHQiOnsidHlwZSI6IkNvbnRleHQifX19LCJTaGFyZSI6eyJhcHBsaWVzVG8iOnsicHJpbmNpcGFsVHlwZXMiOlsiVXNlciIsIldvcmtsb2FkIl0sInJlc291cmNlVHlwZXMiOlsiQXBwbGljYXRpb24iXSwiY29udGV4dCI6eyJ0eXBlIjoiQ29udGV4dCJ9fX0sIlRhZyI6eyJhcHBsaWVzVG8iOnsicHJpbmNpcGFsVHlwZXMiOlsiVXNlciIsIldvcmtsb2FkIl0sInJlc291cmNlVHlwZXMiOlsiQXBwbGljYXRpb24iXSwiY29udGV4dCI6eyJ0eXBlIjoiQ29udGV4dCJ9fX0sIldyaXRlIjp7ImFwcGxpZXNUbyI6eyJwcmluY2lwYWxUeXBlcyI6WyJVc2VyIiwiV29ya2xvYWQiXSwicmVzb3VyY2VUeXBlcyI6WyJBcHBsaWNhdGlvbiIsIlNlY3JldERvY3VtZW50Il0sImNvbnRleHQiOnsidHlwZSI6IkNvbnRleHQifX19fX19"
"schema": "eyJKYW5zIjp7ImNvbW1vblR5cGVzIjp7IkNvbnRleHQiOnsidHlwZSI6IlJlY29yZCIsImF0dHJpYnV0ZXMiOnsiY3VycmVudF90aW1lIjp7InR5cGUiOiJFbnRpdHlPckNvbW1vbiIsInJlcXVpcmVkIjpmYWxzZSwibmFtZSI6IkxvbmcifSwiZGV2aWNlX2hlYWx0aCI6eyJ0eXBlIjoiU2V0IiwicmVxdWlyZWQiOmZhbHNlLCJlbGVtZW50Ijp7InR5cGUiOiJFbnRpdHlPckNvbW1vbiIsIm5hbWUiOiJTdHJpbmcifX0sImZyYXVkX2luZGljYXRvcnMiOnsidHlwZSI6IlNldCIsInJlcXVpcmVkIjpmYWxzZSwiZWxlbWVudCI6eyJ0eXBlIjoiRW50aXR5T3JDb21tb24iLCJuYW1lIjoiU3RyaW5nIn19LCJnZW9sb2NhdGlvbiI6eyJ0eXBlIjoiU2V0IiwicmVxdWlyZWQiOmZhbHNlLCJlbGVtZW50Ijp7InR5cGUiOiJFbnRpdHlPckNvbW1vbiIsIm5hbWUiOiJTdHJpbmcifX0sIm5ldHdvcmsiOnsidHlwZSI6IkVudGl0eU9yQ29tbW9uIiwicmVxdWlyZWQiOmZhbHNlLCJuYW1lIjoiU3RyaW5nIn0sIm5ldHdvcmtfdHlwZSI6eyJ0eXBlIjoiRW50aXR5T3JDb21tb24iLCJyZXF1aXJlZCI6ZmFsc2UsIm5hbWUiOiJTdHJpbmcifSwib3BlcmF0aW5nX3N5c3RlbSI6eyJ0eXBlIjoiRW50aXR5T3JDb21tb24iLCJyZXF1aXJlZCI6ZmFsc2UsIm5hbWUiOiJTdHJpbmcifSwidG9rZW5zIjp7InR5cGUiOiJFbnRpdHlPckNvbW1vbiIsInJlcXVpcmVkIjpmYWxzZSwibmFtZSI6IlRva2Vuc0NvbnRleHQifSwidXNlcl9hZ2VudCI6eyJ0eXBlIjoiRW50aXR5T3JDb21tb24iLCJyZXF1aXJlZCI6ZmFsc2UsIm5hbWUiOiJTdHJpbmcifX19LCJlbWFpbF9hZGRyZXNzIjp7InR5cGUiOiJSZWNvcmQiLCJhdHRyaWJ1dGVzIjp7ImRvbWFpbiI6eyJ0eXBlIjoiRW50aXR5T3JDb21tb24iLCJuYW1lIjoiU3RyaW5nIn0sInVpZCI6eyJ0eXBlIjoiRW50aXR5T3JDb21tb24iLCJuYW1lIjoiU3RyaW5nIn19fSwiVG9rZW5zQ29udGV4dCI6eyJ0eXBlIjoiUmVjb3JkIiwiYXR0cmlidXRlcyI6eyJ0b3RhbF90b2tlbl9jb3VudCI6eyJ0eXBlIjoiRW50aXR5T3JDb21tb24iLCJuYW1lIjoiTG9uZyJ9fX0sIlVybCI6eyJ0eXBlIjoiUmVjb3JkIiwiYXR0cmlidXRlcyI6eyJob3N0Ijp7InR5cGUiOiJFbnRpdHlPckNvbW1vbiIsIm5hbWUiOiJTdHJpbmcifSwicGF0aCI6eyJ0eXBlIjoiRW50aXR5T3JDb21tb24iLCJuYW1lIjoiU3RyaW5nIn0sInByb3RvY29sIjp7InR5cGUiOiJFbnRpdHlPckNvbW1vbiIsIm5hbWUiOiJTdHJpbmcifX19fSwiZW50aXR5VHlwZXMiOnsiQWNjZXNzX3Rva2VuIjp7InNoYXBlIjp7InR5cGUiOiJSZWNvcmQiLCJhdHRyaWJ1dGVzIjp7ImF1ZCI6eyJ0eXBlIjoiRW50aXR5T3JDb21tb24iLCJyZXF1aXJlZCI6ZmFsc2UsIm5hbWUiOiJTdHJpbmcifSwiZXhwIjp7InR5cGUiOiJFbnRpdHlPckNvbW1vbiIsInJlcXVpcmVkIjpmYWxzZSwibmFtZSI6IkxvbmcifSwiaWF0Ijp7InR5cGUiOiJFbnRpdHlPckNvbW1vbiIsInJlcXVpcmVkIjpmYWxzZSwibmFtZSI6IkxvbmcifSwiaXNzIjp7InR5cGUiOiJFbnRpdHlPckNvbW1vbiIsInJlcXVpcmVkIjpmYWxzZSwibmFtZSI6IlRydXN0ZWRJc3N1ZXIifSwianRpIjp7InR5cGUiOiJFbnRpdHlPckNvbW1vbiIsInJlcXVpcmVkIjpmYWxzZSwibmFtZSI6IlN0cmluZyJ9LCJuYmYiOnsidHlwZSI6IkVudGl0eU9yQ29tbW9uIiwicmVxdWlyZWQiOmZhbHNlLCJuYW1lIjoiTG9uZyJ9LCJzY29wZSI6eyJ0eXBlIjoiU2V0IiwicmVxdWlyZWQiOmZhbHNlLCJlbGVtZW50Ijp7InR5cGUiOiJFbnRpdHlPckNvbW1vbiIsIm5hbWUiOiJTdHJpbmcifX0sInRva2VuX3R5cGUiOnsidHlwZSI6IkVudGl0eU9yQ29tbW9uIiwicmVxdWlyZWQiOmZhbHNlLCJuYW1lIjoiU3RyaW5nIn0sInZhbGlkYXRlZF9hdCI6eyJ0eXBlIjoiRW50aXR5T3JDb21tb24iLCJyZXF1aXJlZCI6ZmFsc2UsIm5hbWUiOiJMb25nIn19fSwidGFncyI6eyJ0eXBlIjoiU2V0IiwiZWxlbWVudCI6eyJ0eXBlIjoiRW50aXR5T3JDb21tb24iLCJuYW1lIjoiU3RyaW5nIn19fSwiQXBwbGljYXRpb24iOnsic2hhcGUiOnsidHlwZSI6IlJlY29yZCIsImF0dHJpYnV0ZXMiOnsiYXBwX2lkIjp7InR5cGUiOiJFbnRpdHlPckNvbW1vbiIsIm5hbWUiOiJTdHJpbmcifSwibmFtZSI6eyJ0eXBlIjoiRW50aXR5T3JDb21tb24iLCJuYW1lIjoiU3RyaW5nIn0sInVybCI6eyJ0eXBlIjoiRW50aXR5T3JDb21tb24iLCJuYW1lIjoiVXJsIn19fX0sIkhUVFBfUmVxdWVzdCI6eyJzaGFwZSI6eyJ0eXBlIjoiUmVjb3JkIiwiYXR0cmlidXRlcyI6eyJoZWFkZXIiOnsidHlwZSI6IlJlY29yZCIsImF0dHJpYnV0ZXMiOnsiQWNjZXB0Ijp7InR5cGUiOiJFbnRpdHlPckNvbW1vbiIsInJlcXVpcmVkIjpmYWxzZSwibmFtZSI6IlN0cmluZyJ9fX0sInVybCI6eyJ0eXBlIjoiRW50aXR5T3JDb21tb24iLCJuYW1lIjoiVXJsIn19fX0sImlkX3Rva2VuIjp7InNoYXBlIjp7InR5cGUiOiJSZWNvcmQiLCJhdHRyaWJ1dGVzIjp7ImFjciI6eyJ0eXBlIjoiRW50aXR5T3JDb21tb24iLCJyZXF1aXJlZCI6ZmFsc2UsIm5hbWUiOiJTdHJpbmcifSwiYW1yIjp7InR5cGUiOiJTZXQiLCJyZXF1aXJlZCI6ZmFsc2UsImVsZW1lbnQiOnsidHlwZSI6IkVudGl0eU9yQ29tbW9uIiwibmFtZSI6IlN0cmluZyJ9fSwiYXVkIjp7InR5cGUiOiJTZXQiLCJyZXF1aXJlZCI6ZmFsc2UsImVsZW1lbnQiOnsidHlwZSI6IkVudGl0eU9yQ29tbW9uIiwibmFtZSI6IlN0cmluZyJ9fSwiYXpwIjp7InR5cGUiOiJFbnRpdHlPckNvbW1vbiIsInJlcXVpcmVkIjpmYWxzZSwibmFtZSI6IlN0cmluZyJ9LCJiaXJ0aGRhdGUiOnsidHlwZSI6IkVudGl0eU9yQ29tbW9uIiwicmVxdWlyZWQiOmZhbHNlLCJuYW1lIjoiU3RyaW5nIn0sImVtYWlsIjp7InR5cGUiOiJFbnRpdHlPckNvbW1vbiIsInJlcXVpcmVkIjpmYWxzZSwibmFtZSI6ImVtYWlsX2FkZHJlc3MifSwiZXhwIjp7InR5cGUiOiJFbnRpdHlPckNvbW1vbiIsInJlcXVpcmVkIjpmYWxzZSwibmFtZSI6IkxvbmcifSwiaWF0Ijp7InR5cGUiOiJFbnRpdHlPckNvbW1vbiIsInJlcXVpcmVkIjpmYWxzZSwibmFtZSI6IkxvbmcifSwiaXNzIjp7InR5cGUiOiJFbnRpdHlPckNvbW1vbiIsInJlcXVpcmVkIjpmYWxzZSwibmFtZSI6IlRydXN0ZWRJc3N1ZXIifSwianRpIjp7InR5cGUiOiJFbnRpdHlPckNvbW1vbiIsInJlcXVpcmVkIjpmYWxzZSwibmFtZSI6IlN0cmluZyJ9LCJuYW1lIjp7InR5cGUiOiJFbnRpdHlPckNvbW1vbiIsInJlcXVpcmVkIjpmYWxzZSwibmFtZSI6IlN0cmluZyJ9LCJwaG9uZV9udW1iZXIiOnsidHlwZSI6IkVudGl0eU9yQ29tbW9uIiwicmVxdWlyZWQiOmZhbHNlLCJuYW1lIjoiU3RyaW5nIn0sInJvbGUiOnsidHlwZSI6IlNldCIsInJlcXVpcmVkIjpmYWxzZSwiZWxlbWVudCI6eyJ0eXBlIjoiRW50aXR5T3JDb21tb24iLCJuYW1lIjoiU3RyaW5nIn19LCJzdWIiOnsidHlwZSI6IkVudGl0eU9yQ29tbW9uIiwicmVxdWlyZWQiOmZhbHNlLCJuYW1lIjoiU3RyaW5nIn0sInRva2VuX3R5cGUiOnsidHlwZSI6IkVudGl0eU9yQ29tbW9uIiwicmVxdWlyZWQiOmZhbHNlLCJuYW1lIjoiU3RyaW5nIn0sInZhbGlkYXRlZF9hdCI6eyJ0eXBlIjoiRW50aXR5T3JDb21tb24iLCJyZXF1aXJlZCI6ZmFsc2UsIm5hbWUiOiJMb25nIn19fSwidGFncyI6eyJ0eXBlIjoiU2V0IiwiZWxlbWVudCI6eyJ0eXBlIjoiRW50aXR5T3JDb21tb24iLCJuYW1lIjoiU3RyaW5nIn19fSwiUm9sZSI6eyJzaGFwZSI6eyJ0eXBlIjoiUmVjb3JkIiwiYXR0cmlidXRlcyI6e319fSwiU2VjcmV0RG9jdW1lbnQiOnsic2hhcGUiOnsidHlwZSI6IlJlY29yZCIsImF0dHJpYnV0ZXMiOnt9fX0sIlRydXN0ZWRJc3N1ZXIiOnsic2hhcGUiOnsidHlwZSI6IlJlY29yZCIsImF0dHJpYnV0ZXMiOnsiaXNzdWVyX2VudGl0eV9pZCI6eyJ0eXBlIjoiRW50aXR5T3JDb21tb24iLCJuYW1lIjoiVXJsIn19fX0sIlVzZXIiOnsic2hhcGUiOnsidHlwZSI6IlJlY29yZCIsImF0dHJpYnV0ZXMiOnsiZW1haWwiOnsidHlwZSI6IkVudGl0eU9yQ29tbW9uIiwicmVxdWlyZWQiOmZhbHNlLCJuYW1lIjoiZW1haWxfYWRkcmVzcyJ9LCJpZF90b2tlbiI6eyJ0eXBlIjoiRW50aXR5T3JDb21tb24iLCJyZXF1aXJlZCI6ZmFsc2UsIm5hbWUiOiJpZF90b2tlbiJ9LCJwaG9uZV9udW1iZXIiOnsidHlwZSI6IkVudGl0eU9yQ29tbW9uIiwicmVxdWlyZWQiOmZhbHNlLCJuYW1lIjoiU3RyaW5nIn0sInJvbGUiOnsidHlwZSI6IlNldCIsImVsZW1lbnQiOnsidHlwZSI6IkVudGl0eU9yQ29tbW9uIiwibmFtZSI6IlN0cmluZyJ9fSwic3ViIjp7InR5cGUiOiJFbnRpdHlPckNvbW1vbiIsIm5hbWUiOiJTdHJpbmcifSwidXNlcmluZm9fdG9rZW4iOnsidHlwZSI6IkVudGl0eU9yQ29tbW9uIiwicmVxdWlyZWQiOmZhbHNlLCJuYW1lIjoiVXNlcmluZm9fdG9rZW4ifSwidXNlcm5hbWUiOnsidHlwZSI6IkVudGl0eU9yQ29tbW9uIiwicmVxdWlyZWQiOmZhbHNlLCJuYW1lIjoiU3RyaW5nIn19fSwibWVtYmVyT2ZUeXBlcyI6WyJSb2xlIl19LCJVc2VyaW5mb190b2tlbiI6eyJzaGFwZSI6eyJ0eXBlIjoiUmVjb3JkIiwiYXR0cmlidXRlcyI6eyJhdWQiOnsidHlwZSI6IkVudGl0eU9yQ29tbW9uIiwicmVxdWlyZWQiOmZhbHNlLCJuYW1lIjoiU3RyaW5nIn0sImJpcnRoZGF0ZSI6eyJ0eXBlIjoiRW50aXR5T3JDb21tb24iLCJyZXF1aXJlZCI6ZmFsc2UsIm5hbWUiOiJTdHJpbmcifSwiZW1haWwiOnsidHlwZSI6IkVudGl0eU9yQ29tbW9uIiwicmVxdWlyZWQiOmZhbHNlLCJuYW1lIjoiZW1haWxfYWRkcmVzcyJ9LCJleHAiOnsidHlwZSI6IkVudGl0eU9yQ29tbW9uIiwicmVxdWlyZWQiOmZhbHNlLCJuYW1lIjoiTG9uZyJ9LCJpYXQiOnsidHlwZSI6IkVudGl0eU9yQ29tbW9uIiwicmVxdWlyZWQiOmZhbHNlLCJuYW1lIjoiTG9uZyJ9LCJpc3MiOnsidHlwZSI6IkVudGl0eU9yQ29tbW9uIiwicmVxdWlyZWQiOmZhbHNlLCJuYW1lIjoiVHJ1c3RlZElzc3VlciJ9LCJqdGkiOnsidHlwZSI6IkVudGl0eU9yQ29tbW9uIiwicmVxdWlyZWQiOmZhbHNlLCJuYW1lIjoiU3RyaW5nIn0sIm5hbWUiOnsidHlwZSI6IkVudGl0eU9yQ29tbW9uIiwicmVxdWlyZWQiOmZhbHNlLCJuYW1lIjoiU3RyaW5nIn0sInBob25lX251bWJlciI6eyJ0eXBlIjoiRW50aXR5T3JDb21tb24iLCJyZXF1aXJlZCI6ZmFsc2UsIm5hbWUiOiJTdHJpbmcifSwicm9sZSI6eyJ0eXBlIjoiU2V0IiwicmVxdWlyZWQiOmZhbHNlLCJlbGVtZW50Ijp7InR5cGUiOiJFbnRpdHlPckNvbW1vbiIsIm5hbWUiOiJTdHJpbmcifX0sInN1YiI6eyJ0eXBlIjoiRW50aXR5T3JDb21tb24iLCJyZXF1aXJlZCI6ZmFsc2UsIm5hbWUiOiJTdHJpbmcifSwidG9rZW5fdHlwZSI6eyJ0eXBlIjoiRW50aXR5T3JDb21tb24iLCJyZXF1aXJlZCI6ZmFsc2UsIm5hbWUiOiJTdHJpbmcifSwidmFsaWRhdGVkX2F0Ijp7InR5cGUiOiJFbnRpdHlPckNvbW1vbiIsInJlcXVpcmVkIjpmYWxzZSwibmFtZSI6IkxvbmcifX19LCJ0YWdzIjp7InR5cGUiOiJTZXQiLCJlbGVtZW50Ijp7InR5cGUiOiJFbnRpdHlPckNvbW1vbiIsIm5hbWUiOiJTdHJpbmcifX19LCJXb3JrbG9hZCI6eyJzaGFwZSI6eyJ0eXBlIjoiUmVjb3JkIiwiYXR0cmlidXRlcyI6eyJhY2Nlc3NfdG9rZW4iOnsidHlwZSI6IkVudGl0eU9yQ29tbW9uIiwicmVxdWlyZWQiOmZhbHNlLCJuYW1lIjoiQWNjZXNzX3Rva2VuIn0sImNsaWVudF9pZCI6eyJ0eXBlIjoiRW50aXR5T3JDb21tb24iLCJuYW1lIjoiU3RyaW5nIn0sImlzcyI6eyJ0eXBlIjoiRW50aXR5T3JDb21tb24iLCJyZXF1aXJlZCI6ZmFsc2UsIm5hbWUiOiJUcnVzdGVkSXNzdWVyIn0sIm5hbWUiOnsidHlwZSI6IkVudGl0eU9yQ29tbW9uIiwicmVxdWlyZWQiOmZhbHNlLCJuYW1lIjoiU3RyaW5nIn0sInJwX2lkIjp7InR5cGUiOiJFbnRpdHlPckNvbW1vbiIsInJlcXVpcmVkIjpmYWxzZSwibmFtZSI6IlN0cmluZyJ9LCJzcGlmZmVfaWQiOnsidHlwZSI6IkVudGl0eU9yQ29tbW9uIiwicmVxdWlyZWQiOmZhbHNlLCJuYW1lIjoiU3RyaW5nIn19fX19LCJhY3Rpb25zIjp7IkNvbXBhcmUiOnsiYXBwbGllc1RvIjp7InByaW5jaXBhbFR5cGVzIjpbIlVzZXIiLCJXb3JrbG9hZCJdLCJyZXNvdXJjZVR5cGVzIjpbIkFwcGxpY2F0aW9uIl0sImNvbnRleHQiOnsidHlwZSI6IkNvbnRleHQifX19LCJERUxFVEUiOnsiYXBwbGllc1RvIjp7InByaW5jaXBhbFR5cGVzIjpbIldvcmtsb2FkIl0sInJlc291cmNlVHlwZXMiOlsiSFRUUF9SZXF1ZXN0Il0sImNvbnRleHQiOnsidHlwZSI6IkNvbnRleHQifX19LCJFeGVjdXRlIjp7ImFwcGxpZXNUbyI6eyJwcmluY2lwYWxUeXBlcyI6WyJVc2VyIiwiV29ya2xvYWQiXSwicmVzb3VyY2VUeXBlcyI6WyJBcHBsaWNhdGlvbiJdLCJjb250ZXh0Ijp7InR5cGUiOiJDb250ZXh0In19fSwiR0VUIjp7ImFwcGxpZXNUbyI6eyJwcmluY2lwYWxUeXBlcyI6WyJXb3JrbG9hZCJdLCJyZXNvdXJjZVR5cGVzIjpbIkhUVFBfUmVxdWVzdCJdLCJjb250ZXh0Ijp7InR5cGUiOiJDb250ZXh0In19fSwiSEVBRCI6eyJhcHBsaWVzVG8iOnsicHJpbmNpcGFsVHlwZXMiOlsiV29ya2xvYWQiXSwicmVzb3VyY2VUeXBlcyI6WyJIVFRQX1JlcXVlc3QiXSwiY29udGV4dCI6eyJ0eXBlIjoiQ29udGV4dCJ9fX0sIk1vbml0b3IiOnsiYXBwbGllc1RvIjp7InByaW5jaXBhbFR5cGVzIjpbIlVzZXIiLCJXb3JrbG9hZCJdLCJyZXNvdXJjZVR5cGVzIjpbIkFwcGxpY2F0aW9uIl0sImNvbnRleHQiOnsidHlwZSI6IkNvbnRleHQifX19LCJQQVRDSCI6eyJhcHBsaWVzVG8iOnsicHJpbmNpcGFsVHlwZXMiOlsiV29ya2xvYWQiXSwicmVzb3VyY2VUeXBlcyI6WyJIVFRQX1JlcXVlc3QiXSwiY29udGV4dCI6eyJ0eXBlIjoiQ29udGV4dCJ9fX0sIlBPU1QiOnsiYXBwbGllc1RvIjp7InByaW5jaXBhbFR5cGVzIjpbIldvcmtsb2FkIl0sInJlc291cmNlVHlwZXMiOlsiSFRUUF9SZXF1ZXN0Il0sImNvbnRleHQiOnsidHlwZSI6IkNvbnRleHQifX19LCJQVVQiOnsiYXBwbGllc1RvIjp7InByaW5jaXBhbFR5cGVzIjpbIldvcmtsb2FkIl0sInJlc291cmNlVHlwZXMiOlsiSFRUUF9SZXF1ZXN0Il0sImNvbnRleHQiOnsidHlwZSI6IkNvbnRleHQifX19LCJSZWFkIjp7ImFwcGxpZXNUbyI6eyJwcmluY2lwYWxUeXBlcyI6WyJVc2VyIiwiV29ya2xvYWQiXSwicmVzb3VyY2VUeXBlcyI6WyJBcHBsaWNhdGlvbiIsIlNlY3JldERvY3VtZW50Il0sImNvbnRleHQiOnsidHlwZSI6IkNvbnRleHQifX19LCJTZWFyY2giOnsiYXBwbGllc1RvIjp7InByaW5jaXBhbFR5cGVzIjpbIlVzZXIiLCJXb3JrbG9hZCJdLCJyZXNvdXJjZVR5cGVzIjpbIkFwcGxpY2F0aW9uIl0sImNvbnRleHQiOnsidHlwZSI6IkNvbnRleHQifX19LCJTaGFyZSI6eyJhcHBsaWVzVG8iOnsicHJpbmNpcGFsVHlwZXMiOlsiVXNlciIsIldvcmtsb2FkIl0sInJlc291cmNlVHlwZXMiOlsiQXBwbGljYXRpb24iXSwiY29udGV4dCI6eyJ0eXBlIjoiQ29udGV4dCJ9fX0sIlRhZyI6eyJhcHBsaWVzVG8iOnsicHJpbmNpcGFsVHlwZXMiOlsiVXNlciIsIldvcmtsb2FkIl0sInJlc291cmNlVHlwZXMiOlsiQXBwbGljYXRpb24iXSwiY29udGV4dCI6eyJ0eXBlIjoiQ29udGV4dCJ9fX0sIldyaXRlIjp7ImFwcGxpZXNUbyI6eyJwcmluY2lwYWxUeXBlcyI6WyJVc2VyIiwiV29ya2xvYWQiXSwicmVzb3VyY2VUeXBlcyI6WyJBcHBsaWNhdGlvbiIsIlNlY3JldERvY3VtZW50Il0sImNvbnRleHQiOnsidHlwZSI6IkNvbnRleHQifX19fX19"
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial

Schema is base64-encoded; consider storing human-readable version.

The Cedar schema is stored as a base64-encoded blob, making it difficult to review changes and maintain. Consider storing a human-readable .cedarschema file alongside the JSON configuration for easier review and version control of schema changes.

🤖 Prompt for AI Agents
In 449805c83e13f332b1b35eac6ffa93187fbd1c648085.json around line 161 the
"schema" value is a base64-encoded Cedar schema which hinders reviews; decode
the base64 into a human-readable .cedarschema file committed alongside this
JSON, replace the long base64 blob in the JSON with either a short filename
reference (or the plain JSON-schema text) and update any load/serialization
logic or CI/build scripts to re-encode the file where necessary (add an
encode/decode step in CI or a small helper script) so repository stores a
readable schema while runtime still receives the original encoded form.

Comment on lines +1 to +9
@id("user_cannot_write_from_restricted_country")
forbid (
principal is Jans::User,
action == Jans::Action::"Write",
resource is Jans::SecretDocument
) when {
context has geolocation &&
context.geolocation.contains("restricted")
}; No newline at end of file
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Add newline at end of file.

🤖 Prompt for AI Agents
In tarpDemo/28e83add6e203af0d3814f06228e45a0eeb5c1269b08.policy around lines 1
to 9, the file is missing a trailing newline; update the file to end with a
single newline character (ensure the last line breaks with \n) and save so the
file conforms to POSIX newline conventions.

Comment on lines +7 to +8
context has geolocation &&
context.geolocation.contains("restricted")
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Security issue: Substring matching with .contains() will incorrectly block users from allowed countries.

The condition context.geolocation.contains("restricted") uses substring matching, which will incorrectly trigger for:

  • ✅ "restricted" (intended)
  • ❌ "unrestricted" (will incorrectly block users from allowed countries)
  • ❌ "not_restricted" (will incorrectly block)
  • ❌ "restricted_access_allowed" (may incorrectly block)

This could deny legitimate access to users operating from permitted locations.

🔎 Recommended fix using exact equality check
 ) when {
   context has geolocation &&
-  context.geolocation.contains("restricted")
+  context.geolocation == "restricted"
 };

If geolocation contains country codes or a list of restricted locations, use:

 ) when {
   context has geolocation &&
-  context.geolocation.contains("restricted")
+  ["CN", "IR", "KP", "SY"].contains(context.geolocation)
 };
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
context has geolocation &&
context.geolocation.contains("restricted")
context has geolocation &&
context.geolocation == "restricted"
Suggested change
context has geolocation &&
context.geolocation.contains("restricted")
context has geolocation &&
["CN", "IR", "KP", "SY"].contains(context.geolocation)
🤖 Prompt for AI Agents
In tarpDemo/28e83add6e203af0d3814f06228e45a0eeb5c1269b08.policy around lines
7-8, the rule uses substring matching with
context.geolocation.contains("restricted") which will falsely match values like
"unrestricted" or "restricted_access_allowed"; replace the substring check with
an exact membership test: if geolocation is a single value compare for equality
to the exact restricted token, or if it can be a list/CSV parse it into an array
and test membership (e.g., split/trim then check includes) or use a
full-word/anchored match; ensure the comparison is case-normalized if needed and
update the policy to only block when a precise restricted entry is present.

Comment on lines +1 to +9
@id("user_cannot_execute_on_public_network")
forbid (
principal is Jans::User,
action == Jans::Action::"Execute",
resource is Jans::Application
) when {
context has network_type &&
context.network_type == "public"
};
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Policy logic is correct.

The condition properly uses exact equality (context.network_type == "public") to restrict execution on public networks. This is the correct approach for string matching in security contexts.

Add newline at EOF

The file should end with a newline character for POSIX compliance.

🤖 Prompt for AI Agents
In tarpDemo/420184da127304d1b2898761893a974096f6dbade45a.policy around lines 1
to 9, the file is missing a trailing newline at EOF; add a single newline
character at the end of the file so it ends with a newline (POSIX-compliant) and
save the file.

Comment on lines +1 to +6
@id("user_cannot_write_to_secretdocument")
forbid (
principal is Jans::User,
action == Jans::Action::"Write",
resource is Jans::SecretDocument
); No newline at end of file
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Policy logic is correct.

The unconditional forbid rule clearly restricts Jans::User principals from writing to SecretDocument resources. However, ensure a newline is added at the end of the file.

🔎 Add newline at EOF

The file should end with a newline character for POSIX compliance.

🤖 Prompt for AI Agents
In tarpDemo/870eaec25d9c8e9a642c4ed4d08b1ad480e6bc1348c7.policy around lines 1
to 6, the policy is correct but the file is missing a trailing newline; add a
single newline character at the end of the file (ensure the file ends with '\n')
so it conforms to POSIX/EOF conventions.

Comment on lines +1 to +6
@id("user_can_monitor")
permit (
principal is Jans::User,
action == Jans::Action::"Monitor",
resource is Jans::Application
); No newline at end of file
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Policy logic is correct.

The unconditional permit rule appropriately grants Jans::User principals the ability to monitor Jans::Application resources.

Add newline at EOF

The file should end with a newline character for POSIX compliance.

🤖 Prompt for AI Agents
In tarpDemo/b5111ecf0d218da2cdbece83aeb77cb6b479d3b5d85c.policy around lines 1
to 6, the policy is correct but the file is missing a trailing newline; to fix,
open the file and add a single newline character at the end of the file (ensure
the file ends with '\n') then save so it complies with POSIX EOF conventions.

Comment on lines +1 to +6
@id("user_can_execute")
permit (
principal is Jans::User,
action == Jans::Action::"Execute",
resource is Jans::Application
); No newline at end of file
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Policy logic is correct.

The unconditional permit rule appropriately grants Jans::User principals the ability to execute Jans::Application resources.

Add newline at EOF

The file should end with a newline character.

🤖 Prompt for AI Agents
In tarpDemo/e76eb1853f0c6a199ca383cd9714e0113dfd851e079a.policy around lines
1-6, the file is missing a trailing newline at EOF; simply add a single newline
character at the end of the file so it ends with a newline (ensure there is
exactly one newline and no extra whitespace after it).

Comment on lines +1 to +9
@id("cannot_write_if_not_admin")
forbid (
principal is Jans::User,
action == Jans::Action::"Write",
resource is Jans::Application
) when {
principal has role &&
!principal.role.contains("admin")
}; No newline at end of file
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Add newline at end of file.

Cedar policy files should end with a newline character for POSIX compliance and better version control diffs.

🤖 Prompt for AI Agents
In tarpDemo/f38f10e80c6f429153cf97781a4c6bcf29761a04259f.policy around lines
1-9, the file is missing a trailing newline; update the file to ensure it ends
with a single newline character (POSIX EOF newline) so the file terminates with
'\n' and save/commit the change.

Comment on lines +7 to +8
principal has role &&
!principal.role.contains("admin")
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Security issue: Substring matching with .contains() is unsafe for role validation.

The condition !principal.role.contains("admin") will match any string containing "admin" as a substring, including:

  • ✅ "admin" (intended)
  • ⚠️ "administrator" (likely unintended)
  • ⚠️ "not_admin" (unintended - would be blocked despite not being admin)
  • ⚠️ "domain_admin_user" (unintended)

This creates a security risk where users with roles like "not_admin" would be incorrectly denied access, and users with "administrator" might be incorrectly granted access (depending on intent).

🔎 Recommended fix using exact equality check
 ) when {
   principal has role &&
-  !principal.role.contains("admin")
+  principal.role != "admin"
 };

If role is a set/list of roles, use:

 ) when {
   principal has role &&
-  !principal.role.contains("admin")
+  !(principal.role.contains("admin"))
 };

But ensure the role value is exactly "admin", not a partial match. Consider using a dedicated admin role attribute or exact string equality.

🤖 Prompt for AI Agents
In tarpDemo/f38f10e80c6f429153cf97781a4c6bcf29761a04259f.policy around lines 7-8
the condition uses substring matching (!principal.role.contains("admin")) which
produces false positives/negatives; change it to an exact role check: if role is
a single string use equality (principal.role == "admin"), if role is a
collection check membership (!("admin" in principal.role) or
principal.role.containsExact("admin") depending on policy language), and also
normalize/trim the value (case/whitespace) if needed to avoid accidental
mismatches.

@ossdhaval ossdhaval merged commit 039d7eb into JanssenProject:main Jan 5, 2026
1 of 2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants