permission_forge 0.14.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (406) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +1138 -0
  3. data/LICENSE.txt +21 -0
  4. data/README.md +356 -0
  5. data/app/controllers/concerns/permission_forge/acting_admin.rb +17 -0
  6. data/app/controllers/concerns/permission_forge/api/crud_actions.rb +84 -0
  7. data/app/controllers/concerns/permission_forge/api/nested_resource_lookup.rb +18 -0
  8. data/app/controllers/concerns/permission_forge/api/pagination.rb +50 -0
  9. data/app/controllers/concerns/permission_forge/api/response_renderer.rb +65 -0
  10. data/app/controllers/concerns/permission_forge/api/serializer_resolver.rb +30 -0
  11. data/app/controllers/concerns/permission_forge/api_authentication.rb +40 -0
  12. data/app/controllers/concerns/permission_forge/assignment_authorization.rb +97 -0
  13. data/app/controllers/concerns/permission_forge/audit_log_gate.rb +55 -0
  14. data/app/controllers/concerns/permission_forge/basic_authentication.rb +77 -0
  15. data/app/controllers/concerns/permission_forge/cache_confirmation.rb +32 -0
  16. data/app/controllers/concerns/permission_forge/forgery_protection.rb +29 -0
  17. data/app/controllers/concerns/permission_forge/html_format.rb +40 -0
  18. data/app/controllers/concerns/permission_forge/param_shapes.rb +87 -0
  19. data/app/controllers/concerns/permission_forge/tenant_required.rb +42 -0
  20. data/app/controllers/permission_forge/api/audit_events_controller.rb +33 -0
  21. data/app/controllers/permission_forge/api/base_controller.rb +220 -0
  22. data/app/controllers/permission_forge/api/dashboard_controller.rb +30 -0
  23. data/app/controllers/permission_forge/api/permission_set_group_users_controller.rb +51 -0
  24. data/app/controllers/permission_forge/api/permission_set_groups_controller.rb +71 -0
  25. data/app/controllers/permission_forge/api/permission_set_rules_controller.rb +37 -0
  26. data/app/controllers/permission_forge/api/permission_set_users_controller.rb +105 -0
  27. data/app/controllers/permission_forge/api/permission_sets_controller.rb +87 -0
  28. data/app/controllers/permission_forge/api/resource_actions_controller.rb +58 -0
  29. data/app/controllers/permission_forge/api/resource_fields_controller.rb +30 -0
  30. data/app/controllers/permission_forge/api/resources_controller.rb +56 -0
  31. data/app/controllers/permission_forge/application_controller.rb +198 -0
  32. data/app/controllers/permission_forge/assets_controller.rb +97 -0
  33. data/app/controllers/permission_forge/assignments_controller.rb +266 -0
  34. data/app/controllers/permission_forge/audit_events_controller.rb +94 -0
  35. data/app/controllers/permission_forge/bulk_assignments_controller.rb +108 -0
  36. data/app/controllers/permission_forge/field_lookups_controller.rb +38 -0
  37. data/app/controllers/permission_forge/home_controller.rb +24 -0
  38. data/app/controllers/permission_forge/maintenance_controller.rb +13 -0
  39. data/app/controllers/permission_forge/people_controller.rb +190 -0
  40. data/app/controllers/permission_forge/permission_set_editor.rb +71 -0
  41. data/app/controllers/permission_forge/permission_set_group_users_controller.rb +57 -0
  42. data/app/controllers/permission_forge/permission_set_groups_controller.rb +111 -0
  43. data/app/controllers/permission_forge/permission_set_rules_controller.rb +97 -0
  44. data/app/controllers/permission_forge/permission_sets_controller.rb +227 -0
  45. data/app/controllers/permission_forge/preferences_controller.rb +26 -0
  46. data/app/controllers/permission_forge/resource_actions_controller.rb +106 -0
  47. data/app/controllers/permission_forge/resource_fields_controller.rb +129 -0
  48. data/app/controllers/permission_forge/resources_controller.rb +189 -0
  49. data/app/controllers/permission_forge/settings_controller.rb +33 -0
  50. data/app/frontend/permission_forge/brand/apple-touch-icon.png +0 -0
  51. data/app/frontend/permission_forge/brand/chevron.svg +1 -0
  52. data/app/frontend/permission_forge/brand/favicon.ico +0 -0
  53. data/app/frontend/permission_forge/brand/favicon.svg +1 -0
  54. data/app/frontend/permission_forge/brand/logo-horizontal-dark.svg +1 -0
  55. data/app/frontend/permission_forge/brand/logo-horizontal-light.svg +1 -0
  56. data/app/frontend/permission_forge/brand/mark-small.svg +1 -0
  57. data/app/frontend/permission_forge/brand/mark.svg +1 -0
  58. data/app/frontend/permission_forge/pf_admin.css +766 -0
  59. data/app/frontend/permission_forge/pf_admin.js +482 -0
  60. data/app/helpers/permission_forge/application_helper.rb +167 -0
  61. data/app/helpers/permission_forge/audit_helper.rb +230 -0
  62. data/app/helpers/permission_forge/audit_sentences_helper.rb +84 -0
  63. data/app/helpers/permission_forge/badges_helper.rb +134 -0
  64. data/app/helpers/permission_forge/changes_helper.rb +117 -0
  65. data/app/helpers/permission_forge/people_helper.rb +118 -0
  66. data/app/helpers/permission_forge/sentences_helper.rb +175 -0
  67. data/app/helpers/permission_forge/settings_helper.rb +152 -0
  68. data/app/helpers/permission_forge/ui_helper.rb +184 -0
  69. data/app/models/permission_forge/audit_event.rb +159 -0
  70. data/app/models/permission_forge/permission_set.rb +100 -0
  71. data/app/models/permission_forge/permission_set_group.rb +83 -0
  72. data/app/models/permission_forge/permission_set_group_user.rb +43 -0
  73. data/app/models/permission_forge/permission_set_rule.rb +99 -0
  74. data/app/models/permission_forge/permission_set_user.rb +158 -0
  75. data/app/models/permission_forge/resource.rb +100 -0
  76. data/app/models/permission_forge/resource_action.rb +58 -0
  77. data/app/models/permission_forge/resource_field.rb +69 -0
  78. data/app/views/layouts/permission_forge/application.html.erb +30 -0
  79. data/app/views/layouts/permission_forge/fragment.html.erb +2 -0
  80. data/app/views/permission_forge/assignments/_person_options.html.erb +26 -0
  81. data/app/views/permission_forge/assignments/confirm_destroy.html.erb +24 -0
  82. data/app/views/permission_forge/assignments/new.html.erb +99 -0
  83. data/app/views/permission_forge/audit_events/index.html.erb +161 -0
  84. data/app/views/permission_forge/audit_events/show.html.erb +146 -0
  85. data/app/views/permission_forge/bulk_assignments/confirm_revoke.html.erb +21 -0
  86. data/app/views/permission_forge/bulk_assignments/new.html.erb +69 -0
  87. data/app/views/permission_forge/field_lookups/show.html.erb +32 -0
  88. data/app/views/permission_forge/home/_audit_card.html.erb +19 -0
  89. data/app/views/permission_forge/home/_ending_card.html.erb +32 -0
  90. data/app/views/permission_forge/home/_expired_card.html.erb +34 -0
  91. data/app/views/permission_forge/home/_privacy_card.html.erb +67 -0
  92. data/app/views/permission_forge/home/_rules_card.html.erb +23 -0
  93. data/app/views/permission_forge/home/_stale_card.html.erb +39 -0
  94. data/app/views/permission_forge/home/_tidy_card.html.erb +18 -0
  95. data/app/views/permission_forge/home/index.html.erb +69 -0
  96. data/app/views/permission_forge/people/_access_tab.html.erb +58 -0
  97. data/app/views/permission_forge/people/_audit_tab.html.erb +93 -0
  98. data/app/views/permission_forge/people/_effective_field_source.html.erb +11 -0
  99. data/app/views/permission_forge/people/_effective_tab.html.erb +118 -0
  100. data/app/views/permission_forge/people/_effective_why.html.erb +48 -0
  101. data/app/views/permission_forge/people/_why_item.html.erb +19 -0
  102. data/app/views/permission_forge/people/confirm_remove_all.html.erb +27 -0
  103. data/app/views/permission_forge/people/consent_preview.html.erb +39 -0
  104. data/app/views/permission_forge/people/erasure_preview.html.erb +28 -0
  105. data/app/views/permission_forge/people/index.html.erb +78 -0
  106. data/app/views/permission_forge/people/show.html.erb +54 -0
  107. data/app/views/permission_forge/permission_set_groups/confirm_destroy.html.erb +12 -0
  108. data/app/views/permission_forge/permission_set_groups/index.html.erb +55 -0
  109. data/app/views/permission_forge/permission_set_groups/show.html.erb +100 -0
  110. data/app/views/permission_forge/permission_set_rules/_builder.html.erb +145 -0
  111. data/app/views/permission_forge/permission_set_rules/_value_input.html.erb +42 -0
  112. data/app/views/permission_forge/permission_set_rules/confirm_destroy.html.erb +13 -0
  113. data/app/views/permission_forge/permission_set_rules/edit.html.erb +3 -0
  114. data/app/views/permission_forge/permission_set_rules/new.html.erb +3 -0
  115. data/app/views/permission_forge/permission_sets/_assignments_tab.html.erb +74 -0
  116. data/app/views/permission_forge/permission_sets/_audit_tab.html.erb +80 -0
  117. data/app/views/permission_forge/permission_sets/_conditions_tab.html.erb +83 -0
  118. data/app/views/permission_forge/permission_sets/_header.html.erb +36 -0
  119. data/app/views/permission_forge/permission_sets/_records_summary.html.erb +16 -0
  120. data/app/views/permission_forge/permission_sets/_resource_summary.html.erb +11 -0
  121. data/app/views/permission_forge/permission_sets/_resources_tab.html.erb +49 -0
  122. data/app/views/permission_forge/permission_sets/confirm_destroy.html.erb +23 -0
  123. data/app/views/permission_forge/permission_sets/confirm_switch_mode.html.erb +15 -0
  124. data/app/views/permission_forge/permission_sets/index.html.erb +83 -0
  125. data/app/views/permission_forge/permission_sets/new.html.erb +63 -0
  126. data/app/views/permission_forge/permission_sets/review.html.erb +26 -0
  127. data/app/views/permission_forge/permission_sets/show.html.erb +50 -0
  128. data/app/views/permission_forge/resource_actions/_across_sets.html.erb +24 -0
  129. data/app/views/permission_forge/resource_actions/_add_select.html.erb +12 -0
  130. data/app/views/permission_forge/resource_actions/_effect.html.erb +25 -0
  131. data/app/views/permission_forge/resource_actions/_endpoints.html.erb +16 -0
  132. data/app/views/permission_forge/resource_actions/_form.html.erb +44 -0
  133. data/app/views/permission_forge/resource_actions/_managed_note.html.erb +11 -0
  134. data/app/views/permission_forge/resource_actions/confirm_destroy.html.erb +13 -0
  135. data/app/views/permission_forge/resource_actions/new.html.erb +31 -0
  136. data/app/views/permission_forge/resource_actions/show.html.erb +39 -0
  137. data/app/views/permission_forge/resource_fields/_explain.html.erb +24 -0
  138. data/app/views/permission_forge/resource_fields/show.html.erb +186 -0
  139. data/app/views/permission_forge/resources/_actions_tab.html.erb +88 -0
  140. data/app/views/permission_forge/resources/_fields_tab.html.erb +89 -0
  141. data/app/views/permission_forge/resources/_rules_tab.html.erb +55 -0
  142. data/app/views/permission_forge/resources/_sync.html.erb +57 -0
  143. data/app/views/permission_forge/resources/confirm_destroy.html.erb +17 -0
  144. data/app/views/permission_forge/resources/new.html.erb +57 -0
  145. data/app/views/permission_forge/resources/show.html.erb +117 -0
  146. data/app/views/permission_forge/settings/_ladder.html.erb +15 -0
  147. data/app/views/permission_forge/settings/_row.html.erb +38 -0
  148. data/app/views/permission_forge/settings/show.html.erb +67 -0
  149. data/app/views/permission_forge/shared/_across_sets.html.erb +31 -0
  150. data/app/views/permission_forge/shared/_audit_events.html.erb +36 -0
  151. data/app/views/permission_forge/shared/_audit_footer.html.erb +16 -0
  152. data/app/views/permission_forge/shared/_audit_off_note.html.erb +15 -0
  153. data/app/views/permission_forge/shared/_audit_pagination.html.erb +19 -0
  154. data/app/views/permission_forge/shared/_audit_refused_note.html.erb +7 -0
  155. data/app/views/permission_forge/shared/_audit_timeline.html.erb +29 -0
  156. data/app/views/permission_forge/shared/_crud_cell.html.erb +18 -0
  157. data/app/views/permission_forge/shared/_dialog_frame.html.erb +11 -0
  158. data/app/views/permission_forge/shared/_expiry_picker.html.erb +27 -0
  159. data/app/views/permission_forge/shared/_head_extra.html.erb +3 -0
  160. data/app/views/permission_forge/shared/_help_banner.html.erb +10 -0
  161. data/app/views/permission_forge/shared/_level_control.html.erb +18 -0
  162. data/app/views/permission_forge/shared/_mode_banners.html.erb +22 -0
  163. data/app/views/permission_forge/shared/_nav.html.erb +12 -0
  164. data/app/views/permission_forge/shared/_preferences.html.erb +24 -0
  165. data/app/views/permission_forge/shared/_reason_field.html.erb +20 -0
  166. data/app/views/permission_forge/shared/_savebar.html.erb +13 -0
  167. data/app/views/permission_forge/shared/_sheet_frame.html.erb +22 -0
  168. data/app/views/permission_forge/shared/_sidebar.html.erb +18 -0
  169. data/app/views/permission_forge/shared/_tech_details.html.erb +20 -0
  170. data/app/views/permission_forge/shared/_toasts.html.erb +27 -0
  171. data/app/views/permission_forge/shared/_topbar.html.erb +15 -0
  172. data/app/views/permission_forge/shared/_user_select.html.erb +16 -0
  173. data/app/views/permission_forge/shared/audit_refused.html.erb +7 -0
  174. data/config/locales/permission_forge.en.yml +2115 -0
  175. data/config/locales/permission_forge.mk.yml +2166 -0
  176. data/config/locales/permission_forge.sq.yml +2164 -0
  177. data/config/routes.rb +143 -0
  178. data/lib/generators/permission_forge/install/install_generator.rb +105 -0
  179. data/lib/generators/permission_forge/install/templates/initializer.rb.tt +148 -0
  180. data/lib/generators/permission_forge/install/templates/migration.rb.tt +198 -0
  181. data/lib/generators/permission_forge/rls/rls_generator.rb +57 -0
  182. data/lib/generators/permission_forge/rls/templates/enable_permission_forge_rls.rb.tt +15 -0
  183. data/lib/generators/permission_forge/upgrade/templates/add_admin_ui_columns.rb.tt +8 -0
  184. data/lib/generators/permission_forge/upgrade/templates/add_audit_events.rb.tt +98 -0
  185. data/lib/generators/permission_forge/upgrade/templates/add_resource_fields_unique_index.rb.tt +69 -0
  186. data/lib/generators/permission_forge/upgrade/upgrade_generator.rb +66 -0
  187. data/lib/permission_forge/admin/action_across_sets.rb +76 -0
  188. data/lib/permission_forge/admin/action_rows.rb +156 -0
  189. data/lib/permission_forge/admin/attention_items.rb +207 -0
  190. data/lib/permission_forge/admin/audit_event_detail.rb +75 -0
  191. data/lib/permission_forge/admin/audit_log.rb +193 -0
  192. data/lib/permission_forge/admin/audit_log_days.rb +41 -0
  193. data/lib/permission_forge/admin/audit_lookups.rb +105 -0
  194. data/lib/permission_forge/admin/audit_name_history.rb +85 -0
  195. data/lib/permission_forge/admin/audit_trail.rb +169 -0
  196. data/lib/permission_forge/admin/bulk_people_matcher.rb +109 -0
  197. data/lib/permission_forge/admin/change_set.rb +123 -0
  198. data/lib/permission_forge/admin/change_set_parts/actions.rb +27 -0
  199. data/lib/permission_forge/admin/change_set_parts/base.rb +58 -0
  200. data/lib/permission_forge/admin/change_set_parts/context.rb +50 -0
  201. data/lib/permission_forge/admin/change_set_parts/field_edit.rb +67 -0
  202. data/lib/permission_forge/admin/change_set_parts/field_levels.rb +71 -0
  203. data/lib/permission_forge/admin/change_set_parts/new_actions.rb +91 -0
  204. data/lib/permission_forge/admin/change_set_parts/new_fields.rb +63 -0
  205. data/lib/permission_forge/admin/change_set_parts/resource_edit.rb +55 -0
  206. data/lib/permission_forge/admin/change_set_parts/resource_flags.rb +19 -0
  207. data/lib/permission_forge/admin/change_set_parts/set_attrs.rb +45 -0
  208. data/lib/permission_forge/admin/change_set_parts/values.rb +20 -0
  209. data/lib/permission_forge/admin/column_fields.rb +48 -0
  210. data/lib/permission_forge/admin/conditions_form.rb +78 -0
  211. data/lib/permission_forge/admin/controller_catalog.rb +166 -0
  212. data/lib/permission_forge/admin/csv.rb +41 -0
  213. data/lib/permission_forge/admin/editable_lock.rb +157 -0
  214. data/lib/permission_forge/admin/effective_access.rb +158 -0
  215. data/lib/permission_forge/admin/effective_fields.rb +176 -0
  216. data/lib/permission_forge/admin/expiry_presets.rb +51 -0
  217. data/lib/permission_forge/admin/exports/document.rb +89 -0
  218. data/lib/permission_forge/admin/exports/events.rb +51 -0
  219. data/lib/permission_forge/admin/exports/holdings.rb +118 -0
  220. data/lib/permission_forge/admin/exports.rb +37 -0
  221. data/lib/permission_forge/admin/field_across_sets.rb +51 -0
  222. data/lib/permission_forge/admin/field_detail.rb +112 -0
  223. data/lib/permission_forge/admin/field_level.rb +74 -0
  224. data/lib/permission_forge/admin/field_rows.rb +137 -0
  225. data/lib/permission_forge/admin/last_changes.rb +94 -0
  226. data/lib/permission_forge/admin/model_catalog.rb +216 -0
  227. data/lib/permission_forge/admin/people_candidates.rb +108 -0
  228. data/lib/permission_forge/admin/people_directory.rb +158 -0
  229. data/lib/permission_forge/admin/permission_set_factory.rb +48 -0
  230. data/lib/permission_forge/admin/person_label.rb +95 -0
  231. data/lib/permission_forge/admin/record_id.rb +19 -0
  232. data/lib/permission_forge/admin/rule_builder.rb +58 -0
  233. data/lib/permission_forge/admin/rule_form.rb +175 -0
  234. data/lib/permission_forge/admin/rule_form_input.rb +74 -0
  235. data/lib/permission_forge/admin/sensitive_columns.rb +68 -0
  236. data/lib/permission_forge/admin/settings_catalog.rb +261 -0
  237. data/lib/permission_forge/admin/settings_values.rb +130 -0
  238. data/lib/permission_forge/api/serializers/audit_event_serializer.rb +27 -0
  239. data/lib/permission_forge/api/serializers/base_serializer.rb +36 -0
  240. data/lib/permission_forge/api/serializers/permission_set_group_serializer.rb +12 -0
  241. data/lib/permission_forge/api/serializers/permission_set_group_user_serializer.rb +11 -0
  242. data/lib/permission_forge/api/serializers/permission_set_rule_serializer.rb +25 -0
  243. data/lib/permission_forge/api/serializers/permission_set_serializer.rb +13 -0
  244. data/lib/permission_forge/api/serializers/permission_set_user_serializer.rb +11 -0
  245. data/lib/permission_forge/api/serializers/resource_action_serializer.rb +13 -0
  246. data/lib/permission_forge/api/serializers/resource_field_serializer.rb +14 -0
  247. data/lib/permission_forge/api/serializers/resource_serializer.rb +15 -0
  248. data/lib/permission_forge/audit/actor.rb +144 -0
  249. data/lib/permission_forge/audit/actor_resolver.rb +103 -0
  250. data/lib/permission_forge/audit/audited_views.rb +208 -0
  251. data/lib/permission_forge/audit/boot_warnings.rb +58 -0
  252. data/lib/permission_forge/audit/column_values.rb +56 -0
  253. data/lib/permission_forge/audit/context.rb +98 -0
  254. data/lib/permission_forge/audit/detached.rb +62 -0
  255. data/lib/permission_forge/audit/event_catalog.rb +110 -0
  256. data/lib/permission_forge/audit/event_query.rb +192 -0
  257. data/lib/permission_forge/audit/failure.rb +47 -0
  258. data/lib/permission_forge/audit/field_access.rb +186 -0
  259. data/lib/permission_forge/audit/gate.rb +167 -0
  260. data/lib/permission_forge/audit/job_context.rb +32 -0
  261. data/lib/permission_forge/audit/log_access.rb +36 -0
  262. data/lib/permission_forge/audit/recorder.rb +168 -0
  263. data/lib/permission_forge/audit/refusals.rb +61 -0
  264. data/lib/permission_forge/audit/request_context.rb +152 -0
  265. data/lib/permission_forge/audit/runtime.rb +178 -0
  266. data/lib/permission_forge/audit/runtime_emission.rb +135 -0
  267. data/lib/permission_forge/audit/settings_observer.rb +70 -0
  268. data/lib/permission_forge/audit/source.rb +54 -0
  269. data/lib/permission_forge/audit/subscribers/base.rb +69 -0
  270. data/lib/permission_forge/audit/subscribers/legacy_hooks.rb +97 -0
  271. data/lib/permission_forge/audit/subscribers/log.rb +45 -0
  272. data/lib/permission_forge/audit/subscribers.rb +58 -0
  273. data/lib/permission_forge/audit.rb +302 -0
  274. data/lib/permission_forge/boot_checks.rb +184 -0
  275. data/lib/permission_forge/cache/backlog.rb +142 -0
  276. data/lib/permission_forge/cache/base.rb +200 -0
  277. data/lib/permission_forge/cache/bulk_invalidation.rb +131 -0
  278. data/lib/permission_forge/cache/failure.rb +171 -0
  279. data/lib/permission_forge/cache/handled_errors.rb +82 -0
  280. data/lib/permission_forge/cache/holder_invalidation.rb +85 -0
  281. data/lib/permission_forge/cache/invalidation.rb +180 -0
  282. data/lib/permission_forge/cache/memory_cache.rb +77 -0
  283. data/lib/permission_forge/cache/null_cache.rb +40 -0
  284. data/lib/permission_forge/cache/rails_cache.rb +231 -0
  285. data/lib/permission_forge/cache/rebuild.rb +149 -0
  286. data/lib/permission_forge/cache/settlement.rb +63 -0
  287. data/lib/permission_forge/cache/user_keys.rb +206 -0
  288. data/lib/permission_forge/cache/variant_removal.rb +55 -0
  289. data/lib/permission_forge/cache/withheld_notice.rb +60 -0
  290. data/lib/permission_forge/concerns/audited_collection.rb +34 -0
  291. data/lib/permission_forge/concerns/auto_permission_scoping.rb +158 -0
  292. data/lib/permission_forge/concerns/controller_action_guard.rb +106 -0
  293. data/lib/permission_forge/concerns/field_mask_checker.rb +45 -0
  294. data/lib/permission_forge/concerns/has_active_scope.rb +12 -0
  295. data/lib/permission_forge/concerns/has_audit_trail.rb +59 -0
  296. data/lib/permission_forge/concerns/has_permission_set_users.rb +115 -0
  297. data/lib/permission_forge/concerns/has_tenant_scoping.rb +86 -0
  298. data/lib/permission_forge/concerns/has_uuid.rb +24 -0
  299. data/lib/permission_forge/concerns/invalidates_in_batch.rb +207 -0
  300. data/lib/permission_forge/concerns/invalidates_managed_actions.rb +80 -0
  301. data/lib/permission_forge/concerns/masked_attributes/alias_access.rb +280 -0
  302. data/lib/permission_forge/concerns/masked_attributes/store_access.rb +100 -0
  303. data/lib/permission_forge/concerns/masked_attributes/validation_reads.rb +153 -0
  304. data/lib/permission_forge/concerns/masked_attributes/virtual_readers.rb +242 -0
  305. data/lib/permission_forge/concerns/masked_attributes.rb +576 -0
  306. data/lib/permission_forge/concerns/permission_cache_accessor.rb +416 -0
  307. data/lib/permission_forge/concerns/permission_scoped_findable.rb +337 -0
  308. data/lib/permission_forge/concerns/permissioned_user.rb +78 -0
  309. data/lib/permission_forge/concerns/permissions_memo.rb +160 -0
  310. data/lib/permission_forge/concerns/permissions_per_context.rb +288 -0
  311. data/lib/permission_forge/concerns/permissions_regenerator.rb +43 -0
  312. data/lib/permission_forge/concerns/records_audit_events.rb +286 -0
  313. data/lib/permission_forge/concerns/resource_permission_checker.rb +116 -0
  314. data/lib/permission_forge/concerns/validates_column_lengths.rb +69 -0
  315. data/lib/permission_forge/concerns/validates_dependency.rb +54 -0
  316. data/lib/permission_forge/conditional_sets.rb +361 -0
  317. data/lib/permission_forge/configuration/admin_ui_settings.rb +108 -0
  318. data/lib/permission_forge/configuration/audit_settings.rb +184 -0
  319. data/lib/permission_forge/configuration/cache_settings.rb +76 -0
  320. data/lib/permission_forge/configuration/controller_action_settings.rb +112 -0
  321. data/lib/permission_forge/configuration/gdpr_settings.rb +70 -0
  322. data/lib/permission_forge/configuration/masked_attributes_settings.rb +83 -0
  323. data/lib/permission_forge/configuration/permits_attributes_settings.rb +26 -0
  324. data/lib/permission_forge/configuration/presets.rb +139 -0
  325. data/lib/permission_forge/configuration/query_scoping_settings.rb +107 -0
  326. data/lib/permission_forge/configuration/strategy_values.rb +57 -0
  327. data/lib/permission_forge/configuration/virtual_attributes_settings.rb +65 -0
  328. data/lib/permission_forge/configuration.rb +624 -0
  329. data/lib/permission_forge/controller_actions/authorizer.rb +171 -0
  330. data/lib/permission_forge/controller_actions/managed_index.rb +213 -0
  331. data/lib/permission_forge/controller_actions/mapping.rb +167 -0
  332. data/lib/permission_forge/controller_actions.rb +122 -0
  333. data/lib/permission_forge/deprecation.rb +86 -0
  334. data/lib/permission_forge/engine.rb +113 -0
  335. data/lib/permission_forge/execution_state.rb +318 -0
  336. data/lib/permission_forge/invalidation_batch.rb +206 -0
  337. data/lib/permission_forge/masked_models.rb +226 -0
  338. data/lib/permission_forge/masking_sync.rb +271 -0
  339. data/lib/permission_forge/model_bindings.rb +90 -0
  340. data/lib/permission_forge/open_transaction.rb +303 -0
  341. data/lib/permission_forge/operators/constants.rb +41 -0
  342. data/lib/permission_forge/operators/registry.rb +300 -0
  343. data/lib/permission_forge/operators/rule_column.rb +120 -0
  344. data/lib/permission_forge/operators/validations.rb +111 -0
  345. data/lib/permission_forge/operators/value_casters/number.rb +68 -0
  346. data/lib/permission_forge/operators/value_casters/temporal.rb +69 -0
  347. data/lib/permission_forge/operators/value_casters.rb +80 -0
  348. data/lib/permission_forge/operators/value_typing.rb +115 -0
  349. data/lib/permission_forge/query_scoping_warnings.rb +68 -0
  350. data/lib/permission_forge/rake_audit.rb +65 -0
  351. data/lib/permission_forge/resource_chain.rb +190 -0
  352. data/lib/permission_forge/rls.rb +209 -0
  353. data/lib/permission_forge/services/attribute_access_guard.rb +138 -0
  354. data/lib/permission_forge/services/audit_event_purger.rb +150 -0
  355. data/lib/permission_forge/services/bulk_permission_set_assignment.rb +108 -0
  356. data/lib/permission_forge/services/concerns/across_tenants.rb +69 -0
  357. data/lib/permission_forge/services/concerns/audited_operation.rb +43 -0
  358. data/lib/permission_forge/services/concerns/clonable.rb +29 -0
  359. data/lib/permission_forge/services/consent_withdrawal_handler.rb +135 -0
  360. data/lib/permission_forge/services/dashboard_stats.rb +43 -0
  361. data/lib/permission_forge/services/data_subject_erasure.rb +306 -0
  362. data/lib/permission_forge/services/expired_assignment_cleaner.rb +152 -0
  363. data/lib/permission_forge/services/extra_field_defaults.rb +71 -0
  364. data/lib/permission_forge/services/field_permission_merger.rb +83 -0
  365. data/lib/permission_forge/services/filters_response_attributes.rb +144 -0
  366. data/lib/permission_forge/services/gdpr_field_auditor/text_report.rb +63 -0
  367. data/lib/permission_forge/services/gdpr_field_auditor.rb +223 -0
  368. data/lib/permission_forge/services/host_key_guard.rb +110 -0
  369. data/lib/permission_forge/services/mask_value.rb +93 -0
  370. data/lib/permission_forge/services/permission_cache_clearer.rb +174 -0
  371. data/lib/permission_forge/services/permission_hash_builder.rb +305 -0
  372. data/lib/permission_forge/services/permission_rule_applier.rb +192 -0
  373. data/lib/permission_forge/services/permission_set_cloner.rb +89 -0
  374. data/lib/permission_forge/services/permission_set_condition_evaluator.rb +102 -0
  375. data/lib/permission_forge/services/permission_set_group_cloner.rb +52 -0
  376. data/lib/permission_forge/services/permits_attributes/nested_records.rb +106 -0
  377. data/lib/permission_forge/services/permits_attributes.rb +270 -0
  378. data/lib/permission_forge/services/resource_field_generator.rb +93 -0
  379. data/lib/permission_forge/services/resource_with_fields_builder.rb +47 -0
  380. data/lib/permission_forge/services/rls_operator_sql.rb +131 -0
  381. data/lib/permission_forge/services/rls_policy_generator.rb +365 -0
  382. data/lib/permission_forge/services/security_audit/action_check.rb +157 -0
  383. data/lib/permission_forge/services/security_audit/assignment_check.rb +120 -0
  384. data/lib/permission_forge/services/security_audit/audit_trail_check.rb +166 -0
  385. data/lib/permission_forge/services/security_audit/base_check.rb +57 -0
  386. data/lib/permission_forge/services/security_audit/config_check.rb +212 -0
  387. data/lib/permission_forge/services/security_audit/integrity_check.rb +105 -0
  388. data/lib/permission_forge/services/security_audit/personal_data_check.rb +79 -0
  389. data/lib/permission_forge/services/security_audit/privilege_check.rb +67 -0
  390. data/lib/permission_forge/services/security_audit/rule_check.rb +141 -0
  391. data/lib/permission_forge/services/security_audit/text_report.rb +46 -0
  392. data/lib/permission_forge/services/security_audit/user_model_check.rb +67 -0
  393. data/lib/permission_forge/services/security_audit.rb +75 -0
  394. data/lib/permission_forge/services/stale_assignment_auditor.rb +68 -0
  395. data/lib/permission_forge/services/unscoped_query_detector.rb +132 -0
  396. data/lib/permission_forge/version.rb +3 -0
  397. data/lib/permission_forge/virtual_fields/discovery.rb +65 -0
  398. data/lib/permission_forge/virtual_fields.rb +102 -0
  399. data/lib/permission_forge.rb +464 -0
  400. data/lib/tasks/permission_forge.rake +31 -0
  401. data/lib/tasks/permission_forge_audit_events.rake +28 -0
  402. data/lib/tasks/permission_forge_cache.rake +26 -0
  403. data/lib/tasks/permission_forge_expiration.rake +30 -0
  404. data/lib/tasks/permission_forge_gdpr.rake +69 -0
  405. data/lib/tasks/permission_forge_rls.rake +38 -0
  406. metadata +515 -0
@@ -0,0 +1,2115 @@
1
+ ---
2
+ en:
3
+ permission_forge:
4
+ api:
5
+ errors:
6
+ action_not_authorized: Action not authorized
7
+ assignment_not_authorized: Assignment not authorized
8
+ field_generation_failed: Could not generate fields for this resource
9
+ forbidden: Forbidden
10
+ not_editable: This record is not editable
11
+ not_found: Record not found
12
+ tenant_required: No tenant is set for this request. The admin API serves one
13
+ tenant at a time.
14
+ assignments:
15
+ confirm_destroy:
16
+ body: "%{name} will lose access to %{resources}, unless another Permission
17
+ Set grants it. This applies immediately."
18
+ body_muting: "%{name} will no longer be restricted by %{set}. Their other
19
+ Permission Sets apply in full. This applies immediately."
20
+ body_nothing: This set doesn't give %{name} any resources, so nothing they
21
+ can see changes.
22
+ crumb: Remove access
23
+ title: Remove “%{set}” from %{name}?
24
+ new:
25
+ already: Already has it
26
+ applies_now: Assigning applies immediately.
27
+ assign: Assign
28
+ assign_many:
29
+ one: Assign %{count} set
30
+ other: Assign %{count} sets
31
+ change: Change
32
+ expires: Expires
33
+ filter_sets: Filter Permission Sets
34
+ forever: with no end date
35
+ muting_notice: "⊘ Muting. %{sets} takes access away from %{name}, whatever
36
+ their other sets allow."
37
+ no_sets: No Permission Sets match.
38
+ person: Person
39
+ summary: "%{name} gets %{sets}, %{until}. This applies immediately."
40
+ this_person: this person
41
+ title: Assign a Permission Set
42
+ title_person: Assign a Permission Set to %{name}
43
+ title_set: Assign “%{set}”
44
+ until: until %{date}
45
+ person_options:
46
+ capped: Showing %{shown} of %{total} matches. Keep typing to narrow it down.
47
+ label: People
48
+ no_match: No one matches “%{query}”. Check the spelling, or search by email.
49
+ nobody: No people to show.
50
+ audit_events:
51
+ index:
52
+ empty_filtered: No events match these filters.
53
+ export: Export
54
+ export_title: Download every event that matches these filters as %{kind}
55
+ filters:
56
+ actor_id: Actor (person id)
57
+ actor_type: Kind of actor
58
+ any_actor_type: Any kind
59
+ any_category: Any category
60
+ any_event: Any event
61
+ any_set: Any Permission Set
62
+ apply: Apply filters
63
+ category: Category
64
+ clear: Clear filters
65
+ correlation_id: Action (correlation id)
66
+ deleted_set: 'Deleted Permission Set #%{id}'
67
+ event: Event
68
+ from: From
69
+ id_placeholder: Id
70
+ label: Filter the audit log
71
+ permission_set: Permission Set
72
+ record_id: Record id
73
+ record_type: Record type
74
+ record_uuid: Record uuid
75
+ subject_user_id: Person (id)
76
+ time_zone: Dates are days in %{zone}.
77
+ to: To
78
+ views: Include views of the log (audit.viewed)
79
+ holdings: Who holds what (CSV)
80
+ holdings_title: Every assignment as it stands, with who granted it, when it
81
+ ends and its last review
82
+ invalid:
83
+ blank: "%{field} is needed for this filter."
84
+ invalid: "%{field}: this value is not valid."
85
+ invalid_value: "%{field}: “%{value}” is not valid."
86
+ title: Check the filters
87
+ newest_first: Newest first
88
+ results:
89
+ one: "%{count} event"
90
+ other: "%{count} events"
91
+ subtitle: Changes to permissions, assignments and reviews recorded while the
92
+ log is on, and who viewed or exported it. These pages never edit or delete
93
+ an event (erasure clears name labels only).
94
+ title: Audit log
95
+ views_hidden: Views of the audit log are hidden here, so they do not bury
96
+ the changes. Exports always include them.
97
+ views_show: Include views of the log
98
+ show:
99
+ actor: Actor
100
+ after: After
101
+ all_by_actor: All events by this actor
102
+ all_for_person: All events about this person
103
+ all_for_record: All events of this record
104
+ all_for_set: All events of this Permission Set
105
+ all_in_action: All events of this action
106
+ attribute: Attribute
107
+ before: Before
108
+ changes: Before and after
109
+ changes_desc:
110
+ one: "%{count} attribute changed"
111
+ other: "%{count} attributes changed"
112
+ correlation: Action
113
+ data: More details
114
+ id: id %{id}
115
+ ip: IP address
116
+ key: Key
117
+ no_data: No further details were recorded.
118
+ no_reason: No reason given
119
+ open_person: Open person
120
+ permission_set: Permission Set
121
+ person: Person
122
+ reason: Reason
123
+ record: Record
124
+ request_id: Request id
125
+ snapshot: Snapshot
126
+ snapshot_desc: The record as it was created.
127
+ snapshot_destroyed: The record as it was when it was removed.
128
+ source: Where
129
+ title: Audit event %{event}
130
+ uuid: Event id
131
+ value: Value
132
+ what: What
133
+ who: Who, where and why
134
+ audit_log:
135
+ actor_named:
136
+ api: "%{name} (API)"
137
+ basic_auth: "%{name} (password prompt)"
138
+ actor_types:
139
+ api: API client
140
+ basic_auth: Password prompt
141
+ system: System
142
+ unknown: Unknown
143
+ user: Person
144
+ boolean:
145
+ 'false': 'No'
146
+ 'true': 'Yes'
147
+ categories:
148
+ access: Access
149
+ admin: Admin
150
+ change: Change
151
+ system: System
152
+ deleted_group: 'Permission Set Group #%{id}'
153
+ deleted_set: 'Permission Set #%{id}'
154
+ details: Details
155
+ empty: No events recorded yet.
156
+ empty_text: "(empty text)"
157
+ filter_actor: Show every event by this actor
158
+ filter_event: Show every %{event} event
159
+ first_page: First
160
+ last_page: Last
161
+ list_label: Audit events, newest first
162
+ no_value: none
163
+ 'off':
164
+ disabled: Recording is switched off (audit_events = false). Changes made now
165
+ are not in the log.
166
+ failing: audit_events is true but the audit table does not exist, so every
167
+ permission change fails. Run bin/rails generate permission_forge:upgrade
168
+ and migrate.
169
+ missing_table: The audit table does not exist yet, so nothing is recorded.
170
+ Run bin/rails generate permission_forge:upgrade and migrate.
171
+ title: The audit log is not recording
172
+ page_of: Page %{page} of %{pages}
173
+ pages_label: Pages
174
+ person_id: 'Person #%{id}'
175
+ reason_inline: 'Reason: %{reason}'
176
+ refused:
177
+ body: Reading the audit log is limited by the audit_log_authorization setting,
178
+ and this request was not allowed. The refusal is recorded in the audit log
179
+ while recording is on.
180
+ title: You can't read the audit log
181
+ sentence_variants:
182
+ assignment_revoked_expired: "%{actor} removed %{set} from %{person} after
183
+ it expired on %{date}."
184
+ field_access_limited: "%{actor} read %{record} with these fields hidden or
185
+ masked: %{fields}."
186
+ sentences:
187
+ access:
188
+ denied: "%{actor} was denied access to %{record}."
189
+ action:
190
+ denied: "%{actor} was denied an action on %{record}."
191
+ admin:
192
+ auth_failed: A request by %{actor} to the admin screens was refused.
193
+ effective_access_viewed: "%{actor} looked at the effective access of %{person}."
194
+ lock_refused: "%{actor} tried to change the locked record %{record}."
195
+ api:
196
+ auth_failed: An API request by %{actor} was refused.
197
+ assignment:
198
+ changed: "%{actor} changed %{person}'s assignment to %{set}."
199
+ granted: "%{actor} gave %{person} the Permission Set %{set}."
200
+ reviewed: "%{actor} reviewed %{person}'s access to %{set}."
201
+ revoked: "%{actor} removed %{set} from %{person}."
202
+ audit:
203
+ exported: "%{actor} exported audit records."
204
+ purged: "%{actor} deleted audit events older than the retention period."
205
+ settings_observed: The audit settings in force were recorded.
206
+ viewed: "%{actor} viewed audit records."
207
+ cache:
208
+ cleared: "%{actor} cleared the cached permissions of every user."
209
+ cleanup:
210
+ expired_assignments: "%{actor} removed expired assignments."
211
+ consent:
212
+ withdrawn: "%{actor} recorded that %{person} withdrew consent; the access
213
+ that needed it was removed."
214
+ erasure:
215
+ performed: "%{actor} erased the permission data of %{person}."
216
+ fallback: "%{actor}: %{event}"
217
+ field:
218
+ access: "%{actor} read %{record}."
219
+ sensitive_acknowledged: "%{actor} confirmed that the field %{record} in
220
+ %{set} is meant to be readable unmasked."
221
+ group_membership:
222
+ added: "%{actor} added %{person} to %{group}."
223
+ changed: "%{actor} changed %{person}'s membership of %{group}."
224
+ removed: "%{actor} removed %{person} from %{group}."
225
+ params:
226
+ filtered: Fields of %{model} that %{actor} may not edit were dropped from
227
+ a request.
228
+ permission_set:
229
+ cloned: "%{actor} created the Permission Set %{record} as a copy."
230
+ created: "%{actor} created the Permission Set %{record}."
231
+ destroyed: "%{actor} deleted the Permission Set %{record}."
232
+ updated: "%{actor} changed the Permission Set %{record}."
233
+ permission_set_group:
234
+ cloned: "%{actor} created the Permission Set Group %{record} as a copy."
235
+ created: "%{actor} created the Permission Set Group %{record}."
236
+ destroyed: "%{actor} deleted the Permission Set Group %{record}."
237
+ updated: "%{actor} changed the Permission Set Group %{record}."
238
+ permission_set_rule:
239
+ created: "%{actor} added the record rule %{record} in %{set}."
240
+ destroyed: "%{actor} removed the record rule %{record} from %{set}."
241
+ updated: "%{actor} changed the record rule %{record} in %{set}."
242
+ permissions:
243
+ invalidated: The cached permissions of %{person} were cleared.
244
+ rebuilt: The permissions of %{person} were rebuilt.
245
+ query:
246
+ unscoped: A query on %{model} for %{actor} ran without record rules.
247
+ report:
248
+ generated: "%{actor} generated a report."
249
+ resource:
250
+ created: "%{actor} added the resource %{record} to %{set}."
251
+ destroyed: "%{actor} removed the resource %{record} from %{set}."
252
+ updated: "%{actor} changed the resource %{record} in %{set}."
253
+ resource_action:
254
+ created: "%{actor} added the action %{record} in %{set}."
255
+ destroyed: "%{actor} removed the action %{record} from %{set}."
256
+ updated: "%{actor} changed the action %{record} in %{set}."
257
+ resource_field:
258
+ created: "%{actor} added the field %{record} in %{set}."
259
+ destroyed: "%{actor} removed the field %{record} from %{set}."
260
+ updated: "%{actor} changed the field %{record} in %{set}."
261
+ rule:
262
+ bypassed: Record rules on %{model} were skipped for %{actor}.
263
+ write:
264
+ masked_skipped: A masked value of %{model} was not written back for %{actor}.
265
+ showing:
266
+ one: "%{from}–%{to} of %{count} event"
267
+ other: "%{from}–%{to} of %{count} events"
268
+ sources:
269
+ admin_ui: Admin screens
270
+ api: API
271
+ console: Console
272
+ job: Background job
273
+ rake: Rake task
274
+ runtime: The app (runtime)
275
+ service: Code
276
+ unknown: unknown
277
+ unknown_group: a Permission Set Group
278
+ bulk_assignments:
279
+ confirm_revoke:
280
+ body: They lose what this set gives them, unless another set grants it. This
281
+ applies immediately.
282
+ confirm:
283
+ one: Revoke from %{count} person
284
+ other: Revoke from %{count} people
285
+ crumb: Revoke
286
+ none: Select at least one person first.
287
+ title:
288
+ one: Revoke “%{set}” from %{count} person?
289
+ other: Revoke “%{set}” from %{count} people?
290
+ new:
291
+ already:
292
+ one: "%{count} already has it"
293
+ other: "%{count} already have it"
294
+ assign: Assign
295
+ assign_count:
296
+ one: Assign to %{count} person
297
+ other: Assign to %{count} people
298
+ check: Check names
299
+ crumb: Bulk assign
300
+ errors:
301
+ nobody: Nobody to assign. Paste emails or names, or pick people.
302
+ not_found:
303
+ one: "%{count} not found"
304
+ other: "%{count} not found"
305
+ paste: Paste emails or names
306
+ paste_hint: One per line, or separated by commas. Only exact matches are used.
307
+ paste_placeholder: |-
308
+ ana@acme.com
309
+ Mark Peterson
310
+ pick: Or pick people
311
+ title: Bulk assign “%{set}”
312
+ will_assign:
313
+ one: "%{count} will be assigned"
314
+ other: "%{count} will be assigned"
315
+ errors:
316
+ admin:
317
+ action_format: Use lowercase letters, numbers and underscores, starting with
318
+ a letter (for example export).
319
+ action_taken: This resource already has an action with that name.
320
+ expiry_missing: Pick an end date, or choose “No expiry”.
321
+ expiry_not_future: The end date must be after today.
322
+ flag: Session flags can only contain letters, numbers, dots, colons, dashes
323
+ and underscores.
324
+ group_blank: Give the group a name.
325
+ ip: 'Line %{line}: “%{ip}” isn''t a valid IP address or CIDR range.'
326
+ person: Choose a person first.
327
+ resource_model: Pick a model from the list.
328
+ resource_taken: This model is already in this Permission Set.
329
+ set_name_blank: Give the Permission Set a name.
330
+ set_name_taken: A Permission Set with this name already exists.
331
+ sets: Choose at least one Permission Set.
332
+ no_authenticated_user: No authenticated user
333
+ rls_requires_postgres: PermissionForge RLS requires PostgreSQL — the current
334
+ database adapter does not support row-level security policies.
335
+ tenant_required: 'No tenant is set for this request. These screens show and
336
+ change one tenant''s permissions at a time: set the tenant in the controller
337
+ they inherit from (base_controller_class), or allow it with config.admin_tenantless_access
338
+ = :allow.'
339
+ unscoped_query: Unscoped query on protected table '%{table}'. Use permission_scoped
340
+ / find_by, enable auto_query_scoping, or wrap intentional access in PermissionForge.without_permission_scope
341
+ { }.
342
+ field_lookups:
343
+ show:
344
+ field: Field
345
+ hint: Only sets that include this resource are listed. Select a row to open
346
+ the field in that set.
347
+ intro: Pick a resource and a field to see its access level in every Permission
348
+ Set.
349
+ no_resources: No Permission Set has any resources yet.
350
+ pick_field: Pick a field…
351
+ pick_resource: Pick a resource…
352
+ who_can_see: Who can see %{field}?
353
+ flash:
354
+ actions:
355
+ created: Added the action “%{action}”.
356
+ deleted: Removed the action “%{action}”.
357
+ updated: Saved “%{action}”. It applies immediately.
358
+ assignment_not_authorized: You are not allowed to make this assignment change.
359
+ Nothing was changed.
360
+ assignments:
361
+ assigned: "%{name} now has %{sets}."
362
+ assigned_until: "%{name} now has %{sets}, until %{date}."
363
+ end_changed: "%{name}'s access to %{set}: %{when}."
364
+ kept: Marked %{name}'s access to %{set} as reviewed today.
365
+ removed: Removed %{set} from %{name}.
366
+ restored: Restored %{set} for %{name}.
367
+ undone: Undone. The assignment was removed.
368
+ bulk_assignments:
369
+ assigned:
370
+ one: Assigned %{set} to %{count} person.
371
+ other: Assigned %{set} to %{count} people.
372
+ revoked:
373
+ one: Revoked %{set} from %{count} person.
374
+ other: Revoked %{set} from %{count} people.
375
+ fields:
376
+ acknowledged: Got it. “%{field}” won't be flagged in the privacy audit again.
377
+ recommendation_applied: Applied the recommended mask to “%{field}”.
378
+ groups:
379
+ created: Created the group “%{name}”.
380
+ deleted: Deleted the group “%{name}”. Its Permission Sets are now not in a
381
+ group.
382
+ duplicated: Duplicated “%{name}” with all its Permission Sets.
383
+ member_added: "%{name} added as a member. This does not give them any Permission
384
+ Sets."
385
+ set_added: Moved “%{set}” into this group.
386
+ set_removed: Removed “%{set}” from this group.
387
+ updated: Group saved. No one's access changed.
388
+ locked_widening: 'This Permission Set is locked: access can be removed or shortened,
389
+ not given or extended.'
390
+ locked_widening_muting: 'This Muting Permission Set is locked: holders can be
391
+ added or kept longer, not removed or given an earlier end date.'
392
+ maintenance:
393
+ cleaned:
394
+ one: Removed %{count} expired assignment.
395
+ other: Removed %{count} expired assignments.
396
+ not_editable: This record is not editable.
397
+ people:
398
+ cache_refresh_failed: Could not refresh %{name}'s cached permissions. The
399
+ cache store did not confirm it, so the old permissions may stay in use until
400
+ the cache lifetime ends. Try again.
401
+ cache_refreshed: Refreshed %{name}'s cached permissions.
402
+ consent_withdrawn:
403
+ one: Removed %{count} Permission Set that needs %{flag}.
404
+ other: Removed %{count} Permission Sets that need %{flag}.
405
+ consent_withdrawn_cache_kept:
406
+ one: Removed %{count} Permission Set that needs %{flag}, but the cache store
407
+ did not confirm that the cached permissions were cleared. The old permissions
408
+ may stay in use until the cache lifetime ends.
409
+ other: Removed %{count} Permission Sets that need %{flag}, but the cache
410
+ store did not confirm that the cached permissions were cleared. The old
411
+ permissions may stay in use until the cache lifetime ends.
412
+ erased: Erased %{name}'s assignments and cached permissions.
413
+ erased_cache_kept: Erased %{name}'s assignments, but the cache store did not
414
+ confirm that their cached permissions were cleared. The old permissions
415
+ may stay in use until the cache lifetime ends.
416
+ removed_all:
417
+ one: Removed %{count} assignment. %{name} has no access through PermissionForge
418
+ now.
419
+ other: Removed %{count} assignments. %{name} has no access through PermissionForge
420
+ now.
421
+ removed_all_cache_kept:
422
+ one: Removed %{count} assignment, but the cache store did not confirm that
423
+ %{name}'s cached permissions were cleared. The old permissions may stay
424
+ in use until the cache lifetime ends.
425
+ other: Removed %{count} assignments, but the cache store did not confirm
426
+ that %{name}'s cached permissions were cleared. The old permissions may
427
+ stay in use until the cache lifetime ends.
428
+ permission_set_group_users:
429
+ add_failed: Could not add user.
430
+ removed: User removed from group.
431
+ user_not_found: User not found.
432
+ permission_sets:
433
+ conditions_saved: Activation conditions saved. They apply immediately.
434
+ created: Created “%{name}”. Nobody has it yet.
435
+ deleted: Deleted “%{name}”.
436
+ duplicated: 'Duplicated “%{name}”: resources, fields, actions and rules were
437
+ copied. Assignments were not.'
438
+ duplicated_outside_group: 'Duplicated “%{name}”: resources, fields, actions
439
+ and rules were copied. Assignments were not. The copy is not in “%{group}”,
440
+ which is locked.'
441
+ no_changes: No changes to save.
442
+ save_failed: 'Nothing was saved: %{errors}'
443
+ saved:
444
+ one: Saved %{count} change. It applies to %{people} now.
445
+ other: Saved %{count} changes. They apply to %{people} now.
446
+ switched_granting: "“%{name}” now grants access."
447
+ switched_muting: "“%{name}” is now a Muting Permission Set."
448
+ resources:
449
+ added:
450
+ one: Added %{resource} with %{count} field.
451
+ other: Added %{resource} with %{count} fields.
452
+ columns_added:
453
+ one: Added %{count} column.
454
+ other: Added %{count} columns.
455
+ missing_removed:
456
+ one: Removed %{count} field whose column no longer exists.
457
+ other: Removed %{count} fields whose columns no longer exist.
458
+ removed: Removed %{resource} from “%{set}”.
459
+ rules:
460
+ created: Added the rule “%{rule}”.
461
+ deleted: Removed the rule “%{rule}”.
462
+ turned_off: Turned off “%{rule}”.
463
+ turned_on: Turned on “%{rule}”.
464
+ updated: Saved the rule “%{rule}”.
465
+ home:
466
+ audit_card:
467
+ failing: The audit table is missing and audit_events is true, so every permission
468
+ change fails. Run the upgrade generator and migrate.
469
+ missing_table: The audit table is missing, so no change is recorded. Run the
470
+ upgrade generator and migrate.
471
+ 'off': Recording is switched off in the initializer (audit_events = false).
472
+ No change is recorded.
473
+ title: The audit log is not recording
474
+ ending_card:
475
+ description: Assignments that end in the next 7 days.
476
+ extend: Extend 30 days
477
+ title: Access ending this week
478
+ expired_card:
479
+ description:
480
+ one: "%{count} expired assignment no longer gives access. Removing it keeps
481
+ lists and audits tidy."
482
+ other: "%{count} expired assignments no longer give access. Removing them
483
+ keeps lists and audits tidy."
484
+ dry_run: Dry run · nothing has changed yet
485
+ item: "%{person} · %{set}"
486
+ preview: Preview cleanup
487
+ remove:
488
+ one: Remove %{count}
489
+ other: Remove %{count}
490
+ title: Clean up expired assignments
491
+ index:
492
+ all_good:
493
+ body: No access is ending this week, there are no expired assignments to
494
+ clean up, every permanent assignment was reviewed in the last %{days}
495
+ days, and the privacy audit found nothing.
496
+ title: Nothing needs your attention
497
+ field_lookup_title: Who can see a field? Pick a resource and a field.
498
+ first_run:
499
+ body: PermissionForge decides who can see and change data in this app. Nobody
500
+ has access through it yet.
501
+ cta: Create your first Permission Set
502
+ steps:
503
+ add:
504
+ body: Pick models from the app, then choose Read, Create, Edit, Delete
505
+ and which fields people see.
506
+ title: Add resources
507
+ assign:
508
+ body: Give the set to people, with an end date if the access is temporary.
509
+ title: Assign it
510
+ create:
511
+ body: A bundle of access you assign to people, like “Sales rep”.
512
+ title: Create a Permission Set
513
+ title: Set up access in 3 steps
514
+ lookup: 'Look up a person: what can they access, and why?'
515
+ people:
516
+ one: "%{count} person has"
517
+ other: "%{count} people have"
518
+ search_placeholder: Look up a person by name or email to see what they can
519
+ access, and why
520
+ sets:
521
+ one: "%{count} active Permission Set"
522
+ other: "%{count} active Permission Sets"
523
+ subtitle: "%{things} · %{people} access through %{sets}."
524
+ things:
525
+ one: "%{count} thing to review"
526
+ other: "%{count} things to review"
527
+ title: Needs attention
528
+ privacy_card:
529
+ description: "%{unmasked}, %{unconfigured}."
530
+ fix: Fix
531
+ intended: This is intended
532
+ per_set_note: Each line looks at one Permission Set on its own. A person who
533
+ also holds another set that configures the field follows that set.
534
+ show_all: Show all %{count}
535
+ title: Privacy audit
536
+ turned_off:
537
+ one: "%{count} sensitive field has its setting turned off."
538
+ other: "%{count} sensitive fields have their setting turned off."
539
+ unconfigured:
540
+ one: "%{count} sensitive column not configured at all"
541
+ other: "%{count} sensitive columns not configured at all"
542
+ unmasked:
543
+ one: "%{count} sensitive field shown unmasked"
544
+ other: "%{count} sensitive fields shown unmasked"
545
+ where: "%{resource} · Readable unmasked in “%{set}” · %{people}"
546
+ where_turned_off: "%{resource} · Its setting in “%{set}” is turned off, so
547
+ it passes through unmasked · %{people}"
548
+ where_turned_off_virtual: "%{resource} · Its setting in “%{set}” is turned
549
+ off, so it is readable and editable by default (virtual field) · %{people}"
550
+ where_unconfigured: "%{resource} · Not configured in “%{set}”, so it passes
551
+ through unmasked · %{people}"
552
+ where_virtual: "%{resource} · Not configured in “%{set}”, so it is readable
553
+ and editable by default (virtual field) · %{people}"
554
+ rules_card:
555
+ join_rules: Automatic query scoping is on, but these rules follow a relationship,
556
+ so it skips them. They only apply where the app uses find_by or permission_scoped.
557
+ open: Open rules
558
+ people:
559
+ one: "%{count} person has this set."
560
+ other: "%{count} people have this set."
561
+ rules:
562
+ one: "%{count} rule on %{resource} in “%{name}”"
563
+ other: "%{count} rules on %{resource} in “%{name}”"
564
+ scoping_off: Automatic query scoping is off, so these rules only apply where
565
+ the app uses find_by or permission_scoped. Other queries (where, all, associations)
566
+ return every record.
567
+ title: Record rules not applied everywhere
568
+ stale_card:
569
+ assigned: Assigned %{date} by %{by}
570
+ description: Not reviewed in over %{days} days. Confirm these people still
571
+ need this access.
572
+ title: Stale assignments
573
+ tidy_card:
574
+ inactive_with_people:
575
+ one: "“%{name}” is turned off, but %{count} person still has it."
576
+ other: "“%{name}” is turned off, but %{count} people still have it."
577
+ inactive_with_people_hint: It gives them nothing while it's off. Turn it back
578
+ on, or remove the assignments.
579
+ no_people: "“%{name}” has no people."
580
+ no_people_hint: Assign it, or delete it if it's no longer needed.
581
+ open: Open set
582
+ title: Permission Sets to tidy up
583
+ layouts:
584
+ application:
585
+ skip_to_content: Skip to content
586
+ title: PermissionForge
587
+ nav:
588
+ audit_log: Audit log
589
+ badge_aria:
590
+ one: "%{count} item needs attention"
591
+ other: "%{count} items need attention"
592
+ groups: Permission Set Groups
593
+ home: Home
594
+ people: People
595
+ permission_sets: Permission Sets
596
+ settings: Settings
597
+ people:
598
+ access_tab:
599
+ assigned: Assigned %{date} by %{by}
600
+ change_end: Change end date
601
+ empty: "%{name} can't see anything through PermissionForge right now."
602
+ groups_html: Also a member of %{groups}. Group membership does not give any
603
+ Permission Sets.
604
+ set_off: This set is turned off, so it currently gives nothing.
605
+ audit_tab:
606
+ assigned_by: Assigned by %{who} · %{date}
607
+ created: 'Created: %{value}'
608
+ disabled: Created-by and edited-by aren't being recorded (audit_trail_enabled
609
+ is off in Settings).
610
+ edited: 'Edited: %{value}'
611
+ events_about: Events about %{name}
612
+ events_by: Actions by %{name}
613
+ kind_group: Group membership (no access)
614
+ kind_muting: Muting Permission Set
615
+ kind_set: Permission Set
616
+ made_by: Changes made by %{name}
617
+ made_by_desc:
618
+ one: Records %{name} created or last edited, newest first. %{count} record.
619
+ other: Records %{name} created or last edited, newest first. %{count} records.
620
+ made_capped: Showing the %{count} most recently edited records of each type.
621
+ The CSV export lists them all.
622
+ made_none: "%{name} hasn't created or edited any PermissionForge records."
623
+ no_assignments: No assignments.
624
+ received: Access received
625
+ timeline: "%{name}'s timeline"
626
+ timeline_desc: Every recorded event that names %{name}, and the changes %{name}
627
+ made while signed in.
628
+ confirm_remove_all:
629
+ body: "%{name} will lose access to %{resources}. This applies immediately."
630
+ body_no_resources: "%{name} will lose every Permission Set below. This applies
631
+ immediately."
632
+ confirm:
633
+ one: Remove %{count} assignment
634
+ other: Remove all %{count} assignments
635
+ crumb: Remove all access
636
+ kept: "%{sets} stay: a locked Muting Permission Set keeps its holders, because
637
+ removing them would give access back."
638
+ nothing: "%{name} has no assignments to remove."
639
+ title: Remove all access for %{name}?
640
+ consent_preview:
641
+ confirm:
642
+ one: Remove %{count}
643
+ other: Remove %{count}
644
+ flag: Consent or session flag
645
+ intro: Removes %{name} from every Permission Set that needs the flag you pick.
646
+ no_flags: "%{name} has no Permission Sets that need a consent or session flag."
647
+ nothing: "%{name} has no Permission Sets that require %{flag}. Nothing would
648
+ change."
649
+ preview: Preview
650
+ title: Withdraw consent
651
+ would_remove:
652
+ one: 'Dry run: %{count} Permission Set would be removed. Nothing has changed
653
+ yet.'
654
+ other: 'Dry run: %{count} Permission Sets would be removed. Nothing has
655
+ changed yet.'
656
+ effective_field_source:
657
+ and_more:
658
+ one: " and %{count} more"
659
+ other: " and %{count} more"
660
+ from: from %{set}
661
+ muted_by: Hidden by %{set}
662
+ none: No set shows it
663
+ unconfigured: Not configured · %{behaviour}
664
+ virtual: Virtual field, readable by default
665
+ effective_tab:
666
+ conditional: "%{sets} only count while their activation conditions are true.
667
+ They're included here."
668
+ fields_visible: "%{visible} of %{total} fields visible"
669
+ grid_label: Effective access
670
+ hidden_by_muting: Hidden by muting
671
+ intro: What %{name} can do right now, with all sets combined. Select any cell
672
+ to see why.
673
+ legend: Legend
674
+ legend_muted: Muted
675
+ legend_none: Not given
676
+ why: Why
677
+ why_empty: Select a cell, field or action to see which Permission Set caused
678
+ it.
679
+ why_label: Explanation
680
+ effective_why:
681
+ action_granted: "%{set} permits this action."
682
+ action_muted: "%{set} blocks this action."
683
+ action_none: No Permission Set permits this action.
684
+ field_capped: Shown as Read-only because Edit isn't allowed on this resource.
685
+ field_from: "%{set} shows this field."
686
+ field_muted: "%{set} hides or masks this field."
687
+ field_none: No Permission Set shows this field.
688
+ field_unconfigured: 'No set configures this column: %{behaviour}.'
689
+ field_variant: Follows the setting of %{base}.
690
+ field_virtual: Virtual field from the model, readable unless a set configures
691
+ it.
692
+ flag_granted: "%{set} gives %{flag}."
693
+ flag_muted: "%{set} mutes %{flag}."
694
+ flag_none: No Permission Set gives %{flag}.
695
+ no_rules: No record rules, so every record is shown.
696
+ note_add_up: 'Permission Sets add up: one grant is enough.'
697
+ note_fields: If several sets show a field, the most open setting wins.
698
+ note_muting: Muting Permission Sets always win over sets that grant access.
699
+ note_rules: Rules from every set apply together.
700
+ records_none: Read isn't allowed, so no records are shown.
701
+ records_title: Which %{resource}
702
+ view_all_from: "%{set} gives View All: every record, record rules skipped."
703
+ erasure_preview:
704
+ assignments:
705
+ one: "%{count} assignment"
706
+ other: "%{count} assignments"
707
+ confirm: Erase permanently
708
+ counts: "%{assignments} · %{groups} · cached permissions"
709
+ eyebrow: GDPR Art. 17 · Irreversible
710
+ groups:
711
+ one: "%{count} group membership"
712
+ other: "%{count} group memberships"
713
+ intro: Deletes this person's assignments and group memberships in this tenant
714
+ and clears their name from the audit log. Audit events (ids, times, IPs,
715
+ reasons) are kept.
716
+ mismatch: The name doesn't match. Nothing was erased.
717
+ title: Data subject erasure
718
+ title_for: Erase %{name}'s access data?
719
+ type_to_confirm_html: Type %{name} to confirm
720
+ untouched: The person's account in the app is not touched. Created-by and
721
+ edited-by fields that point to them are kept.
722
+ index:
723
+ columns:
724
+ ends: Access ends
725
+ person: Person
726
+ sets: Permission Sets
727
+ empty_filter: No one in this view.
728
+ empty_query: No one matches “%{query}”.
729
+ export_holdings: Who holds what (CSV)
730
+ filter_label: Filter people
731
+ filters:
732
+ all: Everyone
733
+ ending: Ending within 7 days
734
+ expired: Expired
735
+ muting: Has a muting set
736
+ no_access: No access
737
+ no_sets: No Permission Sets
738
+ showing: Showing %{from}–%{to} of %{total}. Search by name or email to narrow
739
+ it down.
740
+ subtitle: Everyone in the app, and the Permission Sets assigned to them.
741
+ show:
742
+ actions: Actions
743
+ actions_label: Person actions
744
+ add_set: "+ Add Permission Set"
745
+ menu:
746
+ add:
747
+ desc: Give more access, with an optional end date.
748
+ title: Add a Permission Set
749
+ consent:
750
+ desc: Remove sets that need a consent or session flag.
751
+ title: Withdraw consent…
752
+ erasure:
753
+ desc: GDPR Art. 17. Deletes assignments and group memberships in this
754
+ tenant and clears their name from the audit log.
755
+ title: Data subject erasure…
756
+ refresh:
757
+ desc: 'Rarely needed: changes already apply immediately.'
758
+ title: Refresh cached permissions
759
+ remove_all:
760
+ desc: 'Offboarding: removes every assignment.'
761
+ title: Remove all access
762
+ troubleshooting: Troubleshooting
763
+ tabs:
764
+ access: Access
765
+ audit: Audit
766
+ effective: Effective access
767
+ tabs_label: Person sections
768
+ why_item:
769
+ open_set: Open %{set} →
770
+ permission_set_groups:
771
+ confirm_destroy:
772
+ body:
773
+ one: Its %{count} Permission Set stays and moves to “Not in a group”. No
774
+ one's access changes.
775
+ other: Its %{count} Permission Sets stay and move to “Not in a group”. No
776
+ one's access changes.
777
+ confirm: Delete group
778
+ crumb: Delete
779
+ title: Delete “%{name}”?
780
+ index:
781
+ create: Create group
782
+ empty: No groups yet. Groups organise Permission Sets. Adding someone to a
783
+ group does not give them its sets.
784
+ help_term: Permission Set Group
785
+ help_text: Organises permission sets. Adding someone to a group does not give
786
+ them its sets.
787
+ members_warning:
788
+ one: "%{count} member (doesn't receive these sets)"
789
+ other: "%{count} members (don't receive these sets)"
790
+ name: Group name
791
+ new: New group
792
+ sets_count:
793
+ one: "%{count} Permission Set"
794
+ other: "%{count} Permission Sets"
795
+ subtitle: Organises Permission Sets.
796
+ ungrouped: Not in a group
797
+ show:
798
+ add_member: Add member
799
+ add_set: Add or move a set here
800
+ description: Group description
801
+ description_placeholder: Add a description
802
+ duplicate: Deep duplicate
803
+ duplicate_title:
804
+ one: Copies the group and its %{count} Permission Set with all resources,
805
+ fields, actions and rules.
806
+ other: Copies the group and its %{count} Permission Sets with all resources,
807
+ fields, actions and rules.
808
+ in_group: in %{group}
809
+ members: Members
810
+ members_note_html: Members do <b>not</b> receive this group's Permission Sets.
811
+ To give someone access, assign a Permission Set from their page in People.
812
+ name: Group name
813
+ no_members: No members.
814
+ no_sets: No Permission Sets in this group.
815
+ organisational: Group changes are organisational. They never change anyone's
816
+ access.
817
+ remove_set: Remove from group
818
+ save: Save
819
+ sets: Permission Sets in this group
820
+ permission_set_rules:
821
+ builder:
822
+ active: Rule is active
823
+ advanced: Advanced
824
+ advanced_hint: Join type, active
825
+ condition: Condition
826
+ errors:
827
+ field: Pick the field to check.
828
+ list: Add at least one value to the list.
829
+ name_blank: Give the rule a name.
830
+ range: Enter both ends of the range.
831
+ value: Enter a value, or pick “the current user”.
832
+ field: Field to check
833
+ follow: Follow a relationship
834
+ ignored_warning: View All is on for this resource, so record rules are ignored
835
+ until it's turned off.
836
+ include_nulls: Also show records where %{field} is empty
837
+ join: Join type
838
+ join_note: Only matters when the rule follows a relationship.
839
+ joins:
840
+ auto:
841
+ desc: Uses “%{choice}” for this rule.
842
+ title: Automatic (recommended)
843
+ joins:
844
+ desc: Records without the related record are left out.
845
+ title: Only records that have the related record
846
+ left_joins:
847
+ desc: Records without the related record are kept.
848
+ title: Also records without it
849
+ message: Blocked message
850
+ message_placeholder: Shown when someone opens a record this rule hides.
851
+ model_missing: This model or relationship no longer exists in the app.
852
+ name: Rule name
853
+ name_placeholder: e.g. Own customers
854
+ operator: Condition
855
+ optional: optional
856
+ pick_field: Pick a field…
857
+ preview: Preview
858
+ preview_empty: Pick a field to see the rule as a sentence.
859
+ relationship: Relationship
860
+ remove_step: Remove this relationship step
861
+ save: Save rule
862
+ this_field: this field
863
+ update_form: Update
864
+ confirm_destroy:
865
+ body: People with “%{set}” will see records this rule used to hide. This applies
866
+ immediately.
867
+ title: Remove the rule “%{rule}”?
868
+ edit:
869
+ title: Edit rule for %{resource}
870
+ new:
871
+ title: New rule for %{resource}
872
+ value_input:
873
+ from: From
874
+ no_value: No value needed for this condition.
875
+ or: or
876
+ pick_value: Pick a value…
877
+ to: To
878
+ value: Value
879
+ values: Values
880
+ values_placeholder: draft, sent
881
+ permission_sets:
882
+ assignments_tab:
883
+ assign: Assign to someone
884
+ assigned_on: "%{date} · by %{by}"
885
+ bulk: Bulk assign…
886
+ columns:
887
+ actions: Actions
888
+ assigned: Assigned
889
+ expires: Expires
890
+ person: Person
891
+ empty: Nobody has this Permission Set yet.
892
+ immediate: Assigning or revoking applies immediately.
893
+ label: Assignments
894
+ revoke_selected: Revoke from selected
895
+ select_all: Select everyone shown
896
+ select_hint: Select people to revoke this set from several at once.
897
+ select_person: Select %{name}
898
+ selected:
899
+ one: "%{count} selected"
900
+ other: "%{count} selected"
901
+ audit_tab:
902
+ all_types: All record types
903
+ any_time: Any time
904
+ anyone: Anyone
905
+ columns:
906
+ created: Created
907
+ edited: Last edited
908
+ record: Record
909
+ type: Type
910
+ count:
911
+ one: "%{count} record"
912
+ other: "%{count} records"
913
+ days: Date range
914
+ empty: No records match these filters.
915
+ label: Audit
916
+ last_days:
917
+ one: Last %{count} day
918
+ other: Last %{count} days
919
+ newest_first: Newest first ↓
920
+ oldest_first: Oldest first ↑
921
+ open_log: Open in the audit log
922
+ records: Records in this set
923
+ timeline: Change timeline
924
+ timeline_desc: Every recorded event of this set and its resources, fields,
925
+ actions, rules and assignments (direct assignments; group memberships are
926
+ on the group), newest first. Open an event to see before and after.
927
+ type: Record type
928
+ who: Person
929
+ conditions_tab:
930
+ flag: Session flag
931
+ flag_custom: Or type a flag name
932
+ flag_hint_html: Friendly names come from %{setting} in the initializer.
933
+ flag_intro: The set only counts when the request carries this flag (for example
934
+ after two-factor sign-in).
935
+ from: From
936
+ hours: Allowed hours
937
+ hours_only: Only during certain hours
938
+ intro: When activation conditions are set, this Permission Set only counts
939
+ while all of them are true.
940
+ ips: Allowed IPs or CIDR ranges
941
+ ips_hint: IPv4 and IPv6 are supported, e.g. 10.0.0.0/8 or 2001:db8::/32.
942
+ no_flag: No session flag needed
943
+ one_per_line: one per line
944
+ overnight: 'Overnight: active from %{from} until %{to} the next morning.'
945
+ reset: Reset
946
+ save: Save conditions · applies to %{people}
947
+ server_time: Server time (%{zone})
948
+ to: to
949
+ confirm_destroy:
950
+ body: "%{people} lose what this set gives them (%{resources}) unless another
951
+ set grants it."
952
+ body_muting: "%{people} will no longer be restricted by this set."
953
+ body_nobody: Nobody has this set, so no one's access changes.
954
+ confirm: Delete Permission Set
955
+ crumb: Delete
956
+ irreversible: This can't be undone.
957
+ title: Delete “%{name}”?
958
+ confirm_switch_mode:
959
+ to_granting:
960
+ body: Every setting inverts. Each ⊘ that used to take access away will instead
961
+ give it to the %{people} in this set.
962
+ confirm: Switch to granting
963
+ title: Switch “%{name}” to a granting set?
964
+ to_muting:
965
+ body: Every setting inverts. Each ✓ that used to give access will instead
966
+ take it away from the %{people} in this set, overriding their other sets.
967
+ confirm: Switch to muting
968
+ title: Switch “%{name}” to a Muting Permission Set?
969
+ copy_name: "%{name} (copy)"
970
+ header:
971
+ description: Description
972
+ description_placeholder: Add a description so others know when to use it
973
+ group: Group
974
+ name: Name
975
+ index:
976
+ columns:
977
+ actions: Actions
978
+ group: Group
979
+ people: People
980
+ set: Permission Set
981
+ status: Status
982
+ duplicate_aria: Duplicate %{name}
983
+ empty_body: A Permission Set is a bundle of access you assign to people. Create
984
+ one like “Sales rep”, add resources, then assign it.
985
+ empty_title: No Permission Sets yet
986
+ filter_label: Filter Permission Sets
987
+ filters:
988
+ all: All
989
+ conditional: Conditional
990
+ granting: Grants access
991
+ muting: Muting
992
+ 'off': Turned off
993
+ help_term: Permission Set
994
+ help_text: A bundle of access you assign to people. A Muting Permission Set
995
+ takes access away; it overrides anything other sets grant.
996
+ new: New Permission Set
997
+ no_match: No Permission Sets match. Try another search or filter.
998
+ search: Search Permission Sets
999
+ subtitle: The fastest way to make a new set is to duplicate a similar one.
1000
+ new:
1001
+ blank: Blank
1002
+ copy_of: Copy of %{name}
1003
+ create: Create Permission Set
1004
+ granting:
1005
+ desc: 'Permission Set: a bundle of access you assign to people.'
1006
+ example: 'Example: “Sales rep” can read and edit their own customers.'
1007
+ title: Grants access
1008
+ group: Group
1009
+ muting:
1010
+ desc: 'Muting Permission Set: takes access away. It overrides anything other
1011
+ sets grant.'
1012
+ example: 'Example: “Contractors — no financial data” hides IBAN and blocks
1013
+ Export.'
1014
+ title: Removes access
1015
+ name: Name
1016
+ name_placeholder: e.g. Sales rep
1017
+ note: Copies resources, fields, actions, rules and conditions. Assignments
1018
+ are not copied. You can switch between granting and muting later, but every
1019
+ setting inverts.
1020
+ start_from_granting: Start from
1021
+ start_from_muting: Start from
1022
+ title: New Permission Set
1023
+ type: What should this set do?
1024
+ records_summary:
1025
+ ignored:
1026
+ one: "%{count} rule ignored"
1027
+ other: "%{count} rules ignored"
1028
+ no_rules: No rules · every record
1029
+ view_modify_all: View All · Modify All
1030
+ resource_summary:
1031
+ fields:
1032
+ one: "%{count} field"
1033
+ other: "%{count} fields"
1034
+ masked:
1035
+ one: "%{count} masked"
1036
+ other: "%{count} masked"
1037
+ muting: "%{hidden} hidden · %{masked} force-masked"
1038
+ new:
1039
+ one: "%{count} new"
1040
+ other: "%{count} new"
1041
+ resources_tab:
1042
+ add: Add resource
1043
+ empty: No resources yet. A resource is a model from the app, like Customer.
1044
+ Add one to choose what people with this set can do.
1045
+ label: Resources
1046
+ open: Open
1047
+ open_resource: Open %{resource}
1048
+ review:
1049
+ affected: 'Affected: %{names}.'
1050
+ back: Back
1051
+ body: Saving applies these to %{people} immediately.
1052
+ body_nobody: Nobody has this set yet, so saving affects no one until you assign
1053
+ it.
1054
+ crumb: Review
1055
+ save: Save changes
1056
+ title:
1057
+ one: Review %{count} change
1058
+ other: Review %{count} changes
1059
+ show:
1060
+ and_more:
1061
+ one: "%{count} more"
1062
+ other: "%{count} more"
1063
+ impact: "%{people} affected. Changes apply immediately: %{names}."
1064
+ impact_none: Nobody has this set yet, so changes affect no one until you assign
1065
+ it.
1066
+ 'on': 'on'
1067
+ switch_to_granting: Switch to granting…
1068
+ switch_to_muting: Switch to muting…
1069
+ tabs:
1070
+ assignments: Assignments
1071
+ audit: Audit
1072
+ conditions: Conditions
1073
+ resources: Resources
1074
+ tabs_label: Permission Set sections
1075
+ resource_actions:
1076
+ add_select:
1077
+ block: Add and block
1078
+ none: Don't add
1079
+ not_permitted: Add, not permitted
1080
+ permitted: Add and permit
1081
+ confirm_destroy:
1082
+ body: The action is removed from “%{set}”. This applies immediately.
1083
+ title: Remove the action “%{action}”?
1084
+ effect:
1085
+ managed_elsewhere: Managed by other sets — not permitted here
1086
+ managed_elsewhere_muting: Managed by other sets — not blocked here
1087
+ permitted_by: 'Sets that permit it: %{sets}.'
1088
+ permitted_by_nobody: No Permission Set permits it yet.
1089
+ right_now: 'Right now:'
1090
+ unmanaged_allowed: Not managed — everyone can run it
1091
+ unmanaged_blocked: Not managed — blocked until a set permits it
1092
+ endpoints:
1093
+ guarded: Guarded
1094
+ guarded_title: This controller includes the action guard, so the action is
1095
+ checked on every request.
1096
+ not_guarded: Not guarded
1097
+ not_guarded_title: This controller does not include the action guard, so the
1098
+ action is only checked where your code calls can?.
1099
+ form:
1100
+ block: Block this action
1101
+ description: Description
1102
+ label: Label
1103
+ label_placeholder: e.g. Export to CSV
1104
+ name: Key
1105
+ name_hint: The name your app checks with can?(:export, …). Lowercase, with
1106
+ underscores.
1107
+ name_suggestions: Pick one of this resource's controller actions from the
1108
+ suggestions, or type a key your code checks.
1109
+ permitted: Permitted
1110
+ managed_note:
1111
+ body: As soon as one active Permission Set has a row for an action, only people
1112
+ whose Permission Sets permit it can run it. Everyone else is refused.
1113
+ title: Adding an action makes it managed for everyone
1114
+ unmanaged_allowed: An action no Permission Set manages can be run by everyone.
1115
+ unmanaged_blocked: An action no Permission Set manages is blocked for everyone.
1116
+ new:
1117
+ add: Add action
1118
+ intro: Actions are app-specific verbs your code checks, like Export or Sync
1119
+ to accounting.
1120
+ title: New action for %{resource}
1121
+ where: Where %{action} runs
1122
+ show:
1123
+ unlinked: Not linked to a controller action. That is expected for an action
1124
+ your code checks with can?.
1125
+ where: Where it runs
1126
+ states:
1127
+ blocked: Blocked
1128
+ not_permitted: Not permitted
1129
+ permitted: Permitted
1130
+ unchanged: Unchanged
1131
+ resource_fields:
1132
+ explain:
1133
+ capped: It shows as Read-only because Edit isn't allowed on this resource.
1134
+ full_picture: See everything %{name} can access →
1135
+ granted: "%{name} sees it through %{sets}."
1136
+ muted: "%{name} doesn't see it in full because %{sets} hides or masks it."
1137
+ no_access: "%{name} can't read %{resources}."
1138
+ none: No set shows this field to %{name}.
1139
+ unconfigured: No set configures this column, so the unconfigured-field setting
1140
+ decides for %{name}.
1141
+ virtual_default: "%{name} gets this virtual field by default, readable and
1142
+ editable: one of their sets has no setting for it."
1143
+ show:
1144
+ access_level: Access level
1145
+ across: Across all Permission Sets
1146
+ applied: Applied
1147
+ apply_recommendation: Apply recommendation
1148
+ column: Name (column)
1149
+ custom: "(custom)"
1150
+ custom_link: Custom strategies in Settings
1151
+ description: Description
1152
+ details: Details
1153
+ explain: Explain for a person
1154
+ explain_button: Explain
1155
+ explain_nobody: Nobody can read this resource yet.
1156
+ flags_muting_note: In muting sets these flags mean “remove”.
1157
+ impact: Saving applies to %{people} immediately.
1158
+ label: Label
1159
+ mask_strategy: Mask strategy
1160
+ muting_note: This is a Muting Permission Set. Choices here take access away.
1161
+ no_rules: No rules in this set filter on this field.
1162
+ not_configured: 'No setting for this column in “%{set}”. With the current
1163
+ configuration it is: %{behaviour}.'
1164
+ not_configured_implicit: 'No setting for this field in “%{set}”. It follows
1165
+ “Virtual fields without a setting”: with the current configuration it is
1166
+ readable and editable by default.'
1167
+ pick_person: Pick a person…
1168
+ save: Save
1169
+ sensitive: 'Matches privacy pattern “%{pattern}”. Recommended: Masked (%{strategy}).'
1170
+ turned_off: 'The setting for this field in “%{set}” is turned off, so it does
1171
+ not apply. With the current configuration the field is: %{behaviour}.'
1172
+ turned_off_implicit: 'The setting for this field in “%{set}” is turned off,
1173
+ so it does not apply. The field follows “Virtual fields without a setting”:
1174
+ with the current configuration it is readable and editable by default.'
1175
+ used_by_rules: Used by rules
1176
+ variants: 'Also applies to:'
1177
+ variants_muting: 'Muting this also mutes:'
1178
+ virtual_discovered_html: 'Virtual field: not a database column. Found on the
1179
+ model and not listed in %{method}, so it never gets access by default.'
1180
+ virtual_html: 'Virtual field: not a database column. The model exposes it
1181
+ through %{method}.'
1182
+ virtual_model_masking_off: This level applies where the app filters parameters
1183
+ and responses. Code that reads the field straight from the model gets the
1184
+ real value.
1185
+ virtual_model_masking_on: This level also applies when code reads the field
1186
+ straight from the model.
1187
+ resources:
1188
+ actions_tab:
1189
+ add: Add action
1190
+ add_aria: Add %{action} to this set
1191
+ bulk_label:
1192
+ one: 'Add %{count} discovered action:'
1193
+ other: 'Add all %{count} discovered actions:'
1194
+ details_aria: Details for %{action}
1195
+ empty: No actions yet. Add the verbs your app checks, like export or sync.
1196
+ empty_discovery: No controller action maps to this resource, and no actions
1197
+ have been added yet.
1198
+ intro: Allow or block app-specific actions for people with this set.
1199
+ intro_muting: Block app-specific actions for people with this set, whatever
1200
+ their other sets allow.
1201
+ no_guard_body_html: Permitting or blocking an action only takes effect where
1202
+ your code calls can?. Include %{guard} in your controllers to check every
1203
+ request.
1204
+ no_guard_title: No controller includes the action guard yet
1205
+ unlinked: Not linked to a controller action
1206
+ unlinked_title: No controller action maps to this key. That is expected for
1207
+ an action your code checks with can?.
1208
+ confirm_destroy:
1209
+ body: "%{people} lose what this set gives them on %{resources}, unless another
1210
+ set grants it."
1211
+ body_muting: "%{people} will no longer be restricted on this resource by this
1212
+ set."
1213
+ confirm: Remove resource
1214
+ title: Remove %{resource} from “%{set}”?
1215
+ fields_tab:
1216
+ details: Details ›
1217
+ details_aria: Details for %{field}
1218
+ field: Field
1219
+ filter_label: Filter fields
1220
+ filters:
1221
+ all: All
1222
+ edit: Editable
1223
+ hidden: Hidden
1224
+ hide: Hidden
1225
+ leave: Unchanged
1226
+ mask: Force mask
1227
+ masked: Masked
1228
+ read: Read-only
1229
+ sensitive: Sensitive
1230
+ unconfigured: Not configured
1231
+ implicit_grant: Editable by default
1232
+ level: Access level
1233
+ level_aria: Access level for %{field}
1234
+ no_match: No fields match.
1235
+ not_configured: Not configured · %{behaviour}
1236
+ read_off: Turn on Read for %{resource} to choose which fields people see.
1237
+ search: Search fields
1238
+ select_all: Select all shown fields
1239
+ select_field: Select %{field}
1240
+ select_hint: Select fields to change several at once.
1241
+ selected:
1242
+ one: "%{count} selected"
1243
+ other: "%{count} selected"
1244
+ set_to: Set to
1245
+ turned_off: Turned off · %{behaviour}
1246
+ new:
1247
+ add: Add
1248
+ already: Already in this set
1249
+ columns:
1250
+ one: "%{count} column"
1251
+ other: "%{count} columns"
1252
+ intro: Pick a model from %{app}. Only real models are listed.
1253
+ models: Models
1254
+ no_models: No models match.
1255
+ note: Fields will be created from the model's columns and virtual fields.
1256
+ note_gdpr: Fields will be created from the model's columns and virtual fields.
1257
+ Privacy defaults are on, so sensitive columns start Masked.
1258
+ presets:
1259
+ block_changes:
1260
+ desc: Mutes Create, Edit, Delete and every action.
1261
+ title: Block all changes
1262
+ full:
1263
+ desc: Read, create, edit and delete. All fields editable.
1264
+ title: Full access
1265
+ hide_sensitive:
1266
+ desc: Hides every column that looks like personal data.
1267
+ title: Hide sensitive fields
1268
+ leave:
1269
+ desc: Nothing muted yet. Set it up yourself.
1270
+ title: Leave everything unchanged
1271
+ nothing:
1272
+ desc: Everything off. Set it up yourself.
1273
+ title: Nothing
1274
+ read:
1275
+ desc: Read only. All fields read-only.
1276
+ title: Read-only
1277
+ search: Search models
1278
+ sensitive:
1279
+ one: "%{count} looks sensitive"
1280
+ other: "%{count} look sensitive"
1281
+ start_from: Start from
1282
+ the_app: the app
1283
+ title: Add a resource
1284
+ rules_tab:
1285
+ add: Add rule
1286
+ all_queries: applies to all queries
1287
+ blocked_message: 'Blocked message: “%{message}”'
1288
+ empty: 'No rules yet, so records aren''t limited: people with this set see
1289
+ every %{resources} they can read.'
1290
+ empty_muting: Muting Permission Sets don't add record rules.
1291
+ empty_view_all: No rules. View All is on, so every record is included anyway.
1292
+ filter_rule: Filter rule · %{applies}
1293
+ ignored: 'Ignored: View All is on'
1294
+ ignored_both: 'Ignored: View All and Modify All are on'
1295
+ join_rule: Follows a relationship · applies to scoped lookups only
1296
+ join_rules_warning: These rules follow a relationship, so automatic query
1297
+ scoping skips them. They only apply where the app uses find_by or permission_scoped.
1298
+ muting: Muting Permission Sets only take access away; record rules come from
1299
+ granting sets.
1300
+ scoped_lookups: applies to scoped lookups only
1301
+ scoping_off: 'Automatic query scoping is off: rules apply to find_by and permission_scoped
1302
+ lookups.'
1303
+ scoping_off_warning: Automatic query scoping is off, so these rules only apply
1304
+ where the app uses find_by or permission_scoped. Other queries return every
1305
+ record.
1306
+ scoping_on: 'Automatic query scoping is on (filter_only): filter rules apply
1307
+ to all queries; rules that follow a relationship only apply to scoped lookups.'
1308
+ turn_off: Turn off
1309
+ turn_on: Turn on
1310
+ show:
1311
+ description: Description
1312
+ description_placeholder: Add a description
1313
+ help_term: Resource
1314
+ help_text: a model from the app (here %{model}). Inside it you choose fields,
1315
+ actions and record rules.
1316
+ impact: "%{people} affected · applies immediately after saving"
1317
+ modify_all_html: "<b>Modify All</b>: edit and delete every %{resource} record.
1318
+ Skips all record rules for changes."
1319
+ modify_all_needs: Needs View All and Edit.
1320
+ muting_hint: Muted actions are removed from people with this set, whatever
1321
+ their other sets allow.
1322
+ muting_note: Settings here take access away from %{set}'s people.
1323
+ needs_read_hint: Edit and Delete need Read.
1324
+ record_scope: Record scope
1325
+ remove: Remove %{resource} from this set…
1326
+ rules_ignored:
1327
+ one: "%{count} rule is currently ignored because View All is on."
1328
+ other: "%{count} rules are currently ignored because View All is on."
1329
+ tabs_label: Resource sections
1330
+ view_all_html: "<b>View All</b>: read every %{resource} record. Skips all
1331
+ record rules for reading."
1332
+ view_all_needs: Needs Read.
1333
+ what_can_do: What people can do
1334
+ sync:
1335
+ add_as:
1336
+ edit: Add all new with full access
1337
+ hidden: Add all new as Hidden
1338
+ hide: Add all new as Hidden
1339
+ read: Add all new as Read-only
1340
+ gdpr_off: Privacy defaults are off.
1341
+ gdpr_on: 'Privacy defaults are on: sensitive columns are added as Masked.'
1342
+ ignored_count:
1343
+ one: "%{count} ignored"
1344
+ other: "%{count} ignored"
1345
+ ignored_link: Settings › Ignored columns
1346
+ ignored_title: Ignored by configuration
1347
+ missing_count:
1348
+ one: "%{count} configured field whose column no longer exists"
1349
+ other: "%{count} configured fields whose columns no longer exist"
1350
+ missing_title: Configured, but the column no longer exists
1351
+ new_count:
1352
+ one: "%{count} new column not configured"
1353
+ other: "%{count} new columns not configured"
1354
+ new_title: New columns, not configured
1355
+ none: None
1356
+ remove_missing: Remove missing fields
1357
+ review: Review
1358
+ sensitive_rec: Sensitive → Masked (%{strategy})
1359
+ title: Sync fields with model
1360
+ settings:
1361
+ items:
1362
+ action_guard_bypass:
1363
+ desc: People for whom controller actions are never checked, for example
1364
+ administrators.
1365
+ name: Who skips the action check
1366
+ action_guard_nil_user_strategy:
1367
+ desc: What the controller guard does with a guarded action when nobody is
1368
+ signed in. Not set, it follows “Record rules with nobody signed in”.
1369
+ name: Guarded actions without a signed-in user
1370
+ admin_app_name:
1371
+ desc: The app name shown under the logo in these screens.
1372
+ name: App name
1373
+ admin_assignment_authorization:
1374
+ desc: Code that decides whether a request may change who holds a Permission
1375
+ Set or belongs to a Permission Set Group, in these screens and in the
1376
+ API. Called with (controller, target, user_ids, action); action is :grant,
1377
+ :revoke, :change_expiry, :review, :add_member or :remove_member. Not set
1378
+ means no extra check.
1379
+ name: Who may change assignments
1380
+ admin_back_url:
1381
+ desc: 'Where the link under the logo leads (default: your app''s home page).'
1382
+ name: '"Back to app" link'
1383
+ admin_docs_url:
1384
+ desc: Where the “Configuration docs” links on this page point to.
1385
+ name: Configuration docs link
1386
+ admin_model_resolver:
1387
+ desc: Which models are offered when you add a resource.
1388
+ name: Models offered in the admin
1389
+ admin_session_flags:
1390
+ desc: Friendly names for session flags offered on the Conditions tab.
1391
+ name: Session flag names
1392
+ admin_stale_assignment_days:
1393
+ desc: Permanent assignments not reviewed for this long appear under Stale
1394
+ assignments.
1395
+ name: Review assignments after
1396
+ admin_tenantless_access:
1397
+ desc: What the admin screens and the admin API do with a request that has
1398
+ no tenant while tenancy is on.
1399
+ name: Requests without a tenant
1400
+ api_action_authorization:
1401
+ desc: Decides which API calls each caller may make.
1402
+ name: API permission check
1403
+ api_assignment_authorization:
1404
+ desc: Decides who may assign Permission Sets through the API.
1405
+ name: API assignment check
1406
+ api_auth:
1407
+ desc: How API callers prove who they are.
1408
+ name: API sign-in
1409
+ api_base_controller_class:
1410
+ desc: The controller API endpoints inherit from.
1411
+ name: API controller
1412
+ api_default_per_page:
1413
+ desc: Records per API page when the caller doesn't say.
1414
+ name: Default page size
1415
+ api_enabled:
1416
+ desc: Lets other systems manage Permission Sets over HTTP.
1417
+ name: JSON API
1418
+ api_max_per_page:
1419
+ desc: Upper limit on records per API page.
1420
+ name: Maximum page size
1421
+ api_pagination_handler:
1422
+ desc: How API results are split into pages.
1423
+ name: Pagination
1424
+ api_record_identifier:
1425
+ desc: Which identifier the API uses in URLs.
1426
+ name: API record identifier
1427
+ api_redact_rule_field_values:
1428
+ desc: Rule values are redacted in API responses.
1429
+ name: Hide rule values in the API
1430
+ api_require_authorization:
1431
+ desc: Refuses API changes when no permission check is configured.
1432
+ name: Require API permission checks
1433
+ api_serializer_overrides:
1434
+ desc: Overrides for how records are written in API responses.
1435
+ name: Custom serializers
1436
+ api_stats_require_admin:
1437
+ desc: Only admins can read usage statistics through the API.
1438
+ name: Stats only for admins
1439
+ audit_actor_resolver:
1440
+ desc: Code that names who acts in a request to these screens or the API.
1441
+ Not set means the signed-in person; under a password prompt, the username.
1442
+ name: Who is recorded as the actor
1443
+ audit_change_failure_strategy:
1444
+ desc: 'What happens when a change cannot be recorded: the change is rolled
1445
+ back (raise), goes through and is reported (report), or goes through and
1446
+ is only logged (log).'
1447
+ name: When a change cannot be recorded
1448
+ audit_events:
1449
+ desc: 'Records each change made through the permission models — the actor
1450
+ as resolved (possibly unknown), when, and the previous values — in the
1451
+ audit log. Auto: on when the audit table exists.'
1452
+ name: Audit log
1453
+ audit_hook_failure_strategy:
1454
+ desc: 'What happens when a subscriber or hook fails while an event is delivered:
1455
+ reported, only logged, or raised.'
1456
+ name: When a subscriber fails
1457
+ audit_log_authorization:
1458
+ desc: Code that decides who may read the audit log pages, tabs, exports
1459
+ and API. Not set means anyone with access to these screens. 'Last edited
1460
+ by' footers and 'Assigned by' labels still show the latest actor to anyone
1461
+ who can open the admin.
1462
+ name: Who may read the audit log
1463
+ audit_log_subscriber:
1464
+ desc: Also writes every audit event to the application log.
1465
+ name: Copy events to the log
1466
+ audit_request_context:
1467
+ desc: Code that gives the request id and IP address stored with each event.
1468
+ Not set means the request id and the remote IP.
1469
+ name: Request details on events
1470
+ audit_retention_period:
1471
+ desc: How long audit events are kept before the purge task may delete them.
1472
+ Not set means forever.
1473
+ name: Keep audit events for
1474
+ audit_runtime_events:
1475
+ desc: 'Which runtime decisions are stored, not only published: denied, bypass,
1476
+ field_read, params_filtered, cache.'
1477
+ name: Stored runtime events
1478
+ audit_trail_enabled:
1479
+ desc: Stores created-by / last-edited-by on PermissionForge records when
1480
+ the actor is a signed-in user.
1481
+ name: Record who created and last edited
1482
+ audit_user_class:
1483
+ desc: The model used for “created by” and “edited by”.
1484
+ name: Audit people model
1485
+ auto_apply_masked_attributes:
1486
+ desc: Applies masking when the app reads attributes directly, not only in
1487
+ responses.
1488
+ name: Mask model attributes automatically
1489
+ auto_query_scoping:
1490
+ desc: Filter rules are added to every query automatically. Rules that follow
1491
+ a relationship only apply to scoped lookups.
1492
+ name: Apply rules to all queries
1493
+ available_locales:
1494
+ desc: Languages these screens are available in.
1495
+ name: Languages
1496
+ base_controller_class:
1497
+ desc: The app controller these screens inherit from. This is where your
1498
+ own sign-in check runs.
1499
+ name: Admin controller
1500
+ cache_backend:
1501
+ desc: Where computed permissions are cached.
1502
+ name: Cache store
1503
+ cache_key_prefix:
1504
+ desc: Prefix for every cache entry.
1505
+ name: Cache key prefix
1506
+ cache_ttl:
1507
+ desc: How long computed permissions are kept. A new value applies to entries
1508
+ cached after the change.
1509
+ name: Cache lifetime
1510
+ conditional_set_cache_ttl:
1511
+ desc: How long permissions are kept for people with conditional sets.
1512
+ name: Conditional set cache lifetime
1513
+ conditional_sets_strict_mode:
1514
+ desc: When request details are missing, strict mode treats conditional sets
1515
+ as inactive.
1516
+ name: Strict activation conditions
1517
+ controller_action_discovery:
1518
+ desc: Shows your app's controller actions on a resource's Actions tab so
1519
+ they can be permitted or blocked.
1520
+ name: List controller actions
1521
+ controller_action_resolver:
1522
+ desc: Decides which resource and action a controller action belongs to.
1523
+ name: Controller action mapping
1524
+ controller_discovery_exclude:
1525
+ desc: Controllers that are never listed or checked.
1526
+ name: Controllers left out
1527
+ current_user_resolver:
1528
+ desc: Tells PermissionForge who is signed in on each request.
1529
+ name: How the current user is found
1530
+ custom_mask_strategies:
1531
+ desc: Extra masking styles defined in code, offered next to the built-in
1532
+ ones.
1533
+ name: Custom mask styles
1534
+ database_row_level_security:
1535
+ desc: Lets the database itself enforce record rules as a last line of defence.
1536
+ name: Database row-level security
1537
+ extra_fields_default_access:
1538
+ desc: Whether a virtual field nobody configured is editable by default or
1539
+ follows “Fields without a setting”.
1540
+ name: Virtual fields without a setting
1541
+ extra_fields_method:
1542
+ desc: Model method that lists extra, non-database fields to protect.
1543
+ name: Virtual fields method
1544
+ field_variant_mappings:
1545
+ desc: A field's setting also applies to these related column names.
1546
+ name: Linked field variants
1547
+ filter_parameters_integration:
1548
+ desc: Adds the privacy patterns to Rails' filter_parameters so logs don't
1549
+ show them.
1550
+ name: Filter sensitive values from logs
1551
+ gdpr_defaults:
1552
+ desc: Columns that look personal get masked by default when they're added.
1553
+ name: Privacy defaults
1554
+ gdpr_field_patterns:
1555
+ desc: Column names matching a pattern are flagged sensitive and get this
1556
+ mask style.
1557
+ name: Sensitive name patterns
1558
+ gdpr_require_explicit_choice:
1559
+ desc: The app refuses to boot until privacy defaults are switched on or
1560
+ off explicitly.
1561
+ name: Require a privacy-defaults choice
1562
+ hidden_attribute_value:
1563
+ desc: What a hidden attribute returns when code reads it.
1564
+ name: Value for hidden attributes
1565
+ http_basic_auth_enabled:
1566
+ desc: Asks for a shared username and password before anyone can open these
1567
+ screens.
1568
+ name: Password-protect this admin
1569
+ http_basic_auth_password:
1570
+ desc: Password for the password prompt above. Never shown here.
1571
+ name: Admin password
1572
+ http_basic_auth_user:
1573
+ desc: Username for the password prompt above.
1574
+ name: Admin username
1575
+ ignored_fields:
1576
+ desc: Columns PermissionForge never manages. They don't appear in field
1577
+ lists.
1578
+ name: Ignored columns
1579
+ mask_virtual_attributes:
1580
+ desc: Also hides or masks computed, non-database fields when your code reads
1581
+ them from the model.
1582
+ name: Mask virtual fields on models
1583
+ masked_attributes_nil_user_strategy:
1584
+ desc: 'Whether masked models return their stored values or hidden ones when
1585
+ there is no current user (jobs, mailers, the console). The user model
1586
+ stays readable: sign-in reads it before anyone is signed in.'
1587
+ name: Masked attributes with nobody signed in
1588
+ masked_write_protection:
1589
+ desc: Stops a masked value like “•••• 4821” from being saved back over the
1590
+ real one.
1591
+ name: Saving masked values
1592
+ nil_user_strategy:
1593
+ desc: Whether rules are skipped, deny everything, or raise an error when
1594
+ there's no current user.
1595
+ name: Record rules with nobody signed in
1596
+ omit_hidden_in_attributes_hash:
1597
+ desc: Hidden fields are removed from attribute hashes instead of being set
1598
+ to empty.
1599
+ name: Leave hidden fields out of attribute lists
1600
+ on_cache_failure:
1601
+ desc: Code that runs when cached permissions could not be cleared, for example
1602
+ to alert you. Until the cache lifetime ends, that person may keep their
1603
+ old permissions.
1604
+ name: When the cache store fails
1605
+ on_field_filtered:
1606
+ desc: Code that runs each time a field is filtered, for example to log it.
1607
+ name: When a field is hidden or masked
1608
+ on_rule_bypass:
1609
+ desc: Code that runs when View All or Modify All skips the record rules.
1610
+ name: When rules are skipped
1611
+ preset:
1612
+ desc: ":strict closes the settings that fail open by default (the README's
1613
+ production hardening checklist), except masking with nobody signed in,
1614
+ which stays an explicit choice; :compat keeps the library defaults. A
1615
+ setting made in the initializer always wins over the preset."
1616
+ name: Preset
1617
+ profile_builder:
1618
+ desc: The profile details cached with each person's permissions.
1619
+ name: Profile details
1620
+ request_context_resolver:
1621
+ desc: Where IP address, time and session flags come from.
1622
+ name: Request details source
1623
+ response_filter_nil_user_strategy:
1624
+ desc: Whether field filtering is skipped or everything is blocked when there
1625
+ is no current user.
1626
+ name: Responses with nobody signed in
1627
+ rls_session_variable:
1628
+ desc: Name of the variable that tells the database who the current user
1629
+ is.
1630
+ name: Database session variable
1631
+ snapshot_transactions:
1632
+ desc: 'Whether a database transaction keeps seeing the data as it was when
1633
+ it began. Permissions computed inside such a transaction are not cached.
1634
+ Auto decides from the database: MySQL and SQLite do, PostgreSQL only at
1635
+ repeatable read or stronger.'
1636
+ name: Transactions read from a snapshot
1637
+ table_name_prefix:
1638
+ desc: Prefix for PermissionForge's own database tables.
1639
+ name: Table prefix
1640
+ tenant_column:
1641
+ desc: Column that holds the tenant on each record.
1642
+ name: Tenant column
1643
+ tenant_model:
1644
+ desc: Model that separates customers of a multi-tenant app.
1645
+ name: Tenant model
1646
+ unconfigured_action_strategy:
1647
+ desc: What happens to a controller action that no Permission Set mentions.
1648
+ name: Actions without a setting
1649
+ unconfigured_field_strategy:
1650
+ desc: What happens to a column that no Permission Set mentions.
1651
+ name: Fields without a setting
1652
+ unscoped_query_detection:
1653
+ desc: Notices queries that skip record rules.
1654
+ name: Detect unprotected queries
1655
+ unscoped_query_detection_environments:
1656
+ desc: Environments where unprotected-query detection is on.
1657
+ name: Detection runs in
1658
+ user_active_check:
1659
+ desc: Tells PermissionForge whether an assigned person's account is still
1660
+ active.
1661
+ name: Active-person check
1662
+ user_class:
1663
+ desc: The model that represents a person who can receive Permission Sets.
1664
+ name: People model
1665
+ user_label_formatter:
1666
+ desc: How a person is shown in lists, for example name and email.
1667
+ name: Person label
1668
+ user_list_limit:
1669
+ desc: Maximum people loaded into a list before asking you to search.
1670
+ name: People list limit
1671
+ user_list_resolver:
1672
+ desc: Which people appear in pickers on these screens.
1673
+ name: People list source
1674
+ uuid_generator:
1675
+ desc: How record UUIDs are created.
1676
+ name: UUID generator
1677
+ virtual_field_discovery:
1678
+ desc: Also lists store accessors and attribute-API attributes as virtual
1679
+ fields.
1680
+ name: Discover virtual fields
1681
+ ladder:
1682
+ active: Active
1683
+ database: Database
1684
+ detect: Detect
1685
+ enforce: Enforce
1686
+ intro: '3 levels of defence: enforce rules on queries, detect queries that
1687
+ skip them, and let the database enforce them.'
1688
+ 'off': 'Off'
1689
+ oks:
1690
+ action_guard_nil_user_strategy: Guarded controller actions are refused when
1691
+ nobody is signed in.
1692
+ admin_tenantless_access: Admin requests without a tenant are refused.
1693
+ api_require_authorization: API changes need a permission check.
1694
+ audit_events: Who changed what is recorded in the audit log.
1695
+ audit_trail_enabled: Stores created-by / last-edited-by on PermissionForge
1696
+ records when the actor is a signed-in user.
1697
+ conditional_sets_strict_mode: Conditional sets fail closed when request info
1698
+ is missing.
1699
+ extra_fields_default_access: Virtual fields nobody configured follow “Fields
1700
+ without a setting”.
1701
+ gdpr_defaults: New sensitive columns start masked.
1702
+ http_basic_auth_enabled: Access to these screens is protected.
1703
+ masked_attributes_nil_user_strategy: Masked models hide their values when
1704
+ nobody is signed in (the user model stays readable for sign-in).
1705
+ masked_write_protection: Masked values are never written back.
1706
+ nil_user_strategy: Code without a signed-in user sees no records.
1707
+ preset: The :strict preset closes the settings that fail open by default.
1708
+ unconfigured_action_strategy: Controller actions nobody configured are blocked.
1709
+ risks:
1710
+ admin_tenantless_access: Admin requests without a tenant are served, across
1711
+ every tenant.
1712
+ api_require_authorization: The API is on, and changes are allowed even without
1713
+ a permission check.
1714
+ audit_events: Changes are not recorded in the audit log (switched off, or
1715
+ the audit table is missing). With audit_events = true and no table, every
1716
+ change fails (under the default :raise strategy).
1717
+ audit_trail_enabled: No one is recorded as creating or editing records.
1718
+ conditional_sets_strict_mode: Conditional sets are treated as active when
1719
+ request info is missing (fail-open).
1720
+ http_basic_auth_enabled: These screens are either locked (password prompt
1721
+ on, but no credentials) or unprotected (no password and no custom admin
1722
+ controller).
1723
+ masked_write_protection: Masked values can be saved back over real data.
1724
+ unconfigured_field_strategy: Columns nobody configured are shown unmasked
1725
+ to anyone who can read the resource.
1726
+ row:
1727
+ changed: Changed
1728
+ default: 'Default: %{value}'
1729
+ docs: 'Configuration docs: %{key} ↗'
1730
+ how_to_change: How to change
1731
+ risk: Risk
1732
+ secure: Secure
1733
+ snippet_current: Snippet shows the current value.
1734
+ snippet_recommended: Snippet shows the recommended value.
1735
+ step_deploy: Commit and deploy (or restart the server locally).
1736
+ step_edit: Edit the file above.
1737
+ step_reload: Reload this page to confirm.
1738
+ sections:
1739
+ activation_conditions: Activation conditions
1740
+ admin_access: Admin access
1741
+ admin_api: Admin JSON API
1742
+ admin_ui: Admin screens
1743
+ audit_trail: Audit log
1744
+ caching: Caching
1745
+ controller_actions: Controller actions
1746
+ database: Database & system
1747
+ field_protection: Field protection
1748
+ masked_attributes: Masked attributes on models
1749
+ multi_tenancy: Multi-tenancy
1750
+ people: People
1751
+ preset: Preset
1752
+ privacy: Privacy (GDPR)
1753
+ record_rules: Record rules & query scoping
1754
+ show:
1755
+ api_disabled_html: API is disabled (%{key}).
1756
+ changed_count:
1757
+ one: "%{count} changed"
1758
+ other: "%{count} changed"
1759
+ changed_only: Show only changed from default
1760
+ has_risk: Has a risky setting
1761
+ health: Health summary
1762
+ how_to_fix: How to fix
1763
+ intro_html: Settings are defined in %{file}. Changes require a deploy/restart.
1764
+ This page shows the current values and how to change them.
1765
+ no_match: No settings match.
1766
+ read_only: Read-only
1767
+ search: Search settings
1768
+ section_meta: "%{settings} · %{changed}"
1769
+ secure_count:
1770
+ one: "%{count} security and privacy setting looks good."
1771
+ other: "%{count} security and privacy settings look good."
1772
+ settings_count:
1773
+ one: "%{count} setting"
1774
+ other: "%{count} settings"
1775
+ units:
1776
+ days:
1777
+ one: "%{count} day"
1778
+ other: "%{count} days"
1779
+ hours:
1780
+ one: "%{count} hour"
1781
+ other: "%{count} hours"
1782
+ minutes:
1783
+ one: "%{count} minute"
1784
+ other: "%{count} minutes"
1785
+ people:
1786
+ one: person
1787
+ other: people
1788
+ records:
1789
+ one: record
1790
+ other: records
1791
+ values:
1792
+ disabled: Disabled
1793
+ empty: None
1794
+ hook_custom: Custom (defined in code)
1795
+ hook_default: Default
1796
+ hook_none: Not set
1797
+ never_displayed: never displayed
1798
+ nil: nil (not set)
1799
+ not_set: Not set
1800
+ 'off': 'Off'
1801
+ 'on': 'On'
1802
+ set: Set
1803
+ shared:
1804
+ across_sets:
1805
+ muted_hidden: 'Muted: hidden'
1806
+ none: No Permission Set includes this resource.
1807
+ active: Active
1808
+ audit_footer:
1809
+ created: Created by %{created_by} · %{created_at}
1810
+ disabled: Created-by and edited-by aren't being recorded.
1811
+ edited: Last edited by %{updated_by} · %{updated_at}
1812
+ history: History
1813
+ crud_cell:
1814
+ allowed: Allowed
1815
+ muted: Muted
1816
+ needs_read: Turn on Read first
1817
+ needs_read_short: Needs Read
1818
+ 'no': 'No'
1819
+ unchanged: Unchanged
1820
+ expiry_picker:
1821
+ custom_label: End date
1822
+ default: Default
1823
+ label: When this access ends
1824
+ pick_date: Pick a date
1825
+ presets:
1826
+ 1d: 1 day
1827
+ 1w: 1 week
1828
+ 30d: 30 days
1829
+ custom: Custom date
1830
+ eom: End of month
1831
+ never: No expiry
1832
+ help_banner:
1833
+ got_it: Got it
1834
+ inactive: Inactive
1835
+ level_control:
1836
+ needs_edit: Turn on Edit for %{resource} first
1837
+ mode_banners:
1838
+ duplicate_to_edit: Duplicate to edit
1839
+ locked_body_html: This record has %{flag}, so it's read-only here. Duplicate
1840
+ it to make an editable copy.
1841
+ muting_body: It overrides anything other sets grant. Anything you mute or
1842
+ hide here is removed for its people. Leave a setting on “Unchanged” to let
1843
+ other sets decide.
1844
+ muting_title: 'Muting Permission Set: takes access away'
1845
+ preferences:
1846
+ language: Language
1847
+ signed_in_as: Signed in as %{name}
1848
+ theme: Theme
1849
+ themes:
1850
+ auto: Auto
1851
+ dark: Dark
1852
+ light: Light
1853
+ reason_field:
1854
+ hint: Kept with the change in the audit log.
1855
+ label: Reason
1856
+ placeholder: e.g. ticket SEC-142
1857
+ summary: Add a reason (optional)
1858
+ summary_short: Reason
1859
+ savebar:
1860
+ clean: No unsaved changes
1861
+ count:
1862
+ one: "%{count} unsaved change"
1863
+ other: "%{count} unsaved changes"
1864
+ discard: Discard
1865
+ label: Unsaved changes
1866
+ note: Saving applies them to %{people} immediately.
1867
+ note_nobody: Nobody has this set yet, so saving affects no one.
1868
+ review: Review and save
1869
+ sidebar:
1870
+ aria: PermissionForge
1871
+ back_to_app: Back to %{app}
1872
+ back_to_app_generic: Back to the app
1873
+ brand: PermissionForge
1874
+ tech_details:
1875
+ copied: Copied
1876
+ copy: Copy
1877
+ summary: Technical details
1878
+ time_ago: "%{time} ago"
1879
+ time_nil: "—"
1880
+ toasts:
1881
+ dismiss: Dismiss
1882
+ undo: Undo
1883
+ topbar:
1884
+ menu: Menu
1885
+ user: User
1886
+ user_fallback: 'User #%{id}'
1887
+ user_select_prompt: Select a person...
1888
+ user_select_truncated: Showing only the first %{count} users. Configure user_list_resolver
1889
+ to narrow this list.
1890
+ ui:
1891
+ actions: Actions
1892
+ apply: Apply
1893
+ assign_set: Assign a Permission Set
1894
+ assignment:
1895
+ never_reviewed: Never reviewed
1896
+ reviewed: Reviewed %{when}
1897
+ reviewed_by: Reviewed by %{who} on %{date}
1898
+ reviewed_on: Reviewed on %{date}
1899
+ audit:
1900
+ system: System
1901
+ types:
1902
+ action: Action
1903
+ assignment: Assignment
1904
+ field: Field
1905
+ group: Group
1906
+ group_membership: Group membership
1907
+ permission_set: Permission Set
1908
+ resource: Resource
1909
+ rule: Rule
1910
+ who_when: "%{who} · %{when}"
1911
+ badges:
1912
+ column_missing: Column missing
1913
+ conditional: Conditional
1914
+ expired: Expired
1915
+ fail_open: Fail-open
1916
+ fail_open_long: 'Fail-open: active when request info is missing'
1917
+ fail_open_title: conditional_sets_strict_mode is off
1918
+ locked: Locked
1919
+ muting: Muting
1920
+ not_configured: Not configured
1921
+ 'off': 'Off'
1922
+ sensitive: Sensitive
1923
+ virtual: Virtual
1924
+ breadcrumb: Breadcrumb
1925
+ cancel: Cancel
1926
+ changes:
1927
+ action_managed_already: "(already managed; sets that permit it: %{sets})"
1928
+ action_managed_first: "(this makes it managed: from now on only people whose
1929
+ Permission Sets permit it can run it)"
1930
+ action_managed_later: "(takes effect once this set and this resource are on)"
1931
+ action_managed_nobody: "(already managed; no Permission Set permits it yet)"
1932
+ action_muted: "%{resource}: %{action} blocked"
1933
+ action_new_muted: "%{resource}: %{action} added and blocked"
1934
+ action_new_off: "%{resource}: %{action} added, not permitted"
1935
+ action_new_on: "%{resource}: %{action} added and permitted"
1936
+ action_new_unmuted: "%{resource}: %{action} added, not blocked"
1937
+ action_off: "%{resource}: %{action} no longer permitted"
1938
+ action_on: "%{resource}: %{action} permitted"
1939
+ action_unmuted: "%{resource}: %{action} no longer blocked"
1940
+ attributes:
1941
+ description: description
1942
+ label: label
1943
+ name: name
1944
+ cascaded: "(switched automatically)"
1945
+ cascaded_field: "(downgraded because Edit is off)"
1946
+ field_level: "%{resource} › %{field}: %{from} → %{to}"
1947
+ field_new: "%{resource} › %{field}: set to %{to}"
1948
+ field_off: "%{resource} › %{field}: turned off"
1949
+ field_on: "%{resource} › %{field}: turned on"
1950
+ field_text: "%{resource} › %{field}: %{attribute} changed"
1951
+ flag_off: "%{resource}: %{flag} removed"
1952
+ flag_off_muting: "%{resource}: %{flag} no longer muted"
1953
+ flag_on: "%{resource}: %{flag} allowed"
1954
+ flag_on_muting: "%{resource}: %{flag} muted"
1955
+ resource_text: "%{resource}: %{attribute} changed"
1956
+ set_group: Moved to the group “%{group}”
1957
+ set_no_group: Removed from its group
1958
+ set_off: Turned the set off
1959
+ set_on: Turned the set on
1960
+ set_text: Permission Set %{attribute} changed
1961
+ close: Close
1962
+ conditions:
1963
+ always: Always active. No activation conditions.
1964
+ flag_generic: when %{flag} is set
1965
+ flags:
1966
+ marketing_consent: when marketing consent is given
1967
+ mfa_verified: after two-factor sign-in
1968
+ sso_login: after company SSO sign-in
1969
+ from_ips: from %{ips}
1970
+ hours: between %{from} and %{to}
1971
+ hours_overnight: between %{from} and %{to} (overnight)
1972
+ only_works: Only works %{parts}.
1973
+ or: " or "
1974
+ dates:
1975
+ days_ago:
1976
+ one: "%{count} day ago"
1977
+ other: "%{count} days ago"
1978
+ never: "—"
1979
+ today: today
1980
+ yesterday: yesterday
1981
+ delete: Delete
1982
+ dry_run: Dry run
1983
+ duplicate: Duplicate
1984
+ edit: Edit
1985
+ expiry:
1986
+ ends_in:
1987
+ one: Ends in %{count} day · %{date}
1988
+ other: Ends in %{count} days · %{date}
1989
+ expired: Expired %{date}
1990
+ none: No expiry
1991
+ today: Ends today
1992
+ until: Until %{date}
1993
+ expiry_change:
1994
+ 1w: 1 week from today
1995
+ 30d: 30 days from today
1996
+ eom: End of month
1997
+ never: No expiry
1998
+ export_csv: Export CSV
1999
+ field_lookup: Field lookup
2000
+ fields: Fields
2001
+ flags:
2002
+ marketing_consent: Has given marketing consent
2003
+ mfa_verified: Signed in with two-factor
2004
+ sso_login: Signed in through company SSO
2005
+ flags_short:
2006
+ create_access: Create
2007
+ delete_access: Delete
2008
+ edit_access: Edit
2009
+ is_active: Active
2010
+ modify_all: Modify All
2011
+ read_access: Read
2012
+ view_all: View All
2013
+ keep: Keep
2014
+ levels:
2015
+ edit: Editable
2016
+ hidden: Hidden
2017
+ hide: Hide
2018
+ leave: Unchanged
2019
+ mask: Force mask
2020
+ masked: Masked
2021
+ muted: Muted
2022
+ none: Not configured
2023
+ read: Read-only
2024
+ locked:
2025
+ title: 'Locked: managed by the system/API'
2026
+ mask_strategies:
2027
+ email: Email
2028
+ first1_last4: First 1 + last 4
2029
+ full: Full
2030
+ last4: Last 4
2031
+ months:
2032
+ apr: Apr
2033
+ aug: Aug
2034
+ dec: Dec
2035
+ feb: Feb
2036
+ jan: Jan
2037
+ jul: Jul
2038
+ jun: Jun
2039
+ mar: Mar
2040
+ may: May
2041
+ nov: Nov
2042
+ oct: Oct
2043
+ sep: Sep
2044
+ next: Next
2045
+ no_group: Not in a group
2046
+ open_person: Open person
2047
+ open_setting: Open setting
2048
+ operators:
2049
+ between: is between
2050
+ contains: contains
2051
+ ends_with: ends with
2052
+ equal: is
2053
+ greater_than: is greater than
2054
+ greater_than_or_equal: is at least
2055
+ in: is one of
2056
+ is_not_null: is not empty
2057
+ is_null: is empty
2058
+ less_than: is less than
2059
+ less_than_or_equal: is at most
2060
+ not_contains: doesn't contain
2061
+ not_equal: is not
2062
+ not_in: is not one of
2063
+ starts_with: starts with
2064
+ people_count:
2065
+ one: "%{count} person"
2066
+ other: "%{count} people"
2067
+ previous: Previous
2068
+ records: Records
2069
+ remove: Remove
2070
+ resource: Resource
2071
+ rules:
2072
+ and: and
2073
+ current_user: the current user
2074
+ only_show: Only show
2075
+ or_empty: or %{field} is empty
2076
+ where: where
2077
+ rules_count:
2078
+ one: Rules (%{count})
2079
+ other: Rules (%{count})
2080
+ rules_tab: Rules
2081
+ search: Search
2082
+ search_people: Search by name or email
2083
+ setting: Setting
2084
+ states:
2085
+ blocked: Blocked
2086
+ granted: Allowed
2087
+ none: 'No'
2088
+ unconfigured:
2089
+ block: Blocked by default
2090
+ mask_all: Fully masked
2091
+ pass_through: Passes through unmasked
2092
+ warn: Passes through and is logged
2093
+ view_all: View All
2094
+ validations:
2095
+ name_blank: can't be blank
2096
+ permission_set:
2097
+ group_missing: must be an existing Permission Set Group
2098
+ permission_set_rule:
2099
+ between_requires_two_values: must contain exactly 2 comma-separated values
2100
+ for between operator
2101
+ field_value_required: is required for this operator
2102
+ in_requires_values: must contain at least 1 comma-separated value
2103
+ invalid_field_name: must be a valid column name (letters, numbers, underscores,
2104
+ dots)
2105
+ invalid_join_type: is not a valid join type
2106
+ invalid_operator: is not a valid operator
2107
+ numeric_or_date_required: must be a numeric or date value for comparison operators
2108
+ value_not_expected: does not require a value for this operator
2109
+ value_required: must not be blank for this operator
2110
+ resource:
2111
+ invalid_name: must be a valid model class name (e.g. Customer or Admin::Report)
2112
+ resource_field:
2113
+ invalid_mask_strategy: is not a valid mask strategy
2114
+ mask_strategy_required: must be present when mask access is enabled
2115
+ too_long: is too long (at most %{count} characters)