@seedgrid/ai-toolkit 0.0.0-stage → 0.3.0
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.
- package/LICENSE +21 -0
- package/README.md +151 -2
- package/dist/adapters/claude.js +114 -0
- package/dist/adapters/codex.js +108 -0
- package/dist/adapters/index.js +17 -0
- package/dist/adapters/shared.js +142 -0
- package/dist/adapters/types.js +1 -0
- package/dist/cli.js +203 -0
- package/dist/commands/common.js +98 -0
- package/dist/commands/doctor.js +290 -0
- package/dist/commands/init.js +9 -0
- package/dist/commands/install.js +107 -0
- package/dist/commands/remove.js +54 -0
- package/dist/commands/review.js +127 -0
- package/dist/commands/status.js +73 -0
- package/dist/commands/update.js +8 -0
- package/dist/commands/validate.js +27 -0
- package/dist/core/apply.js +181 -0
- package/dist/core/blocks.js +64 -0
- package/dist/core/content.js +528 -0
- package/dist/core/env.js +40 -0
- package/dist/core/frontmatter.js +29 -0
- package/dist/core/hash.js +14 -0
- package/dist/core/inspect.js +51 -0
- package/dist/core/lock.js +124 -0
- package/dist/core/paths.js +65 -0
- package/dist/core/plan.js +242 -0
- package/dist/core/tools.js +62 -0
- package/dist/core/types.js +11 -0
- package/dist/core/updates.js +121 -0
- package/docs/arquitetura.md +80 -0
- package/docs/compatibilidade.md +50 -0
- package/docs/formato.md +155 -0
- package/docs/instalacao.md +105 -0
- package/docs/manutencao.md +115 -0
- package/package.json +43 -4
- package/seedgridKB/SeedGrid/Extensions/Catalogo-de-enums.md +161 -0
- package/seedgridKB/SeedGrid/Extensions/Catalogo-de-propriedades.md +971 -0
- package/seedgridKB/SeedGrid/Extensions/Indice.md +63 -0
- package/seedgridKB/SeedGrid/Extensions/ai-pricing/Configuracao.md +124 -0
- package/seedgridKB/SeedGrid/Extensions/ai-pricing/Enums.md +40 -0
- package/seedgridKB/SeedGrid/Extensions/ai-pricing/Exemplos.md +97 -0
- package/seedgridKB/SeedGrid/Extensions/ai-pricing/Visao-geral.md +114 -0
- package/seedgridKB/SeedGrid/Extensions/apikeys/Configuracao-Rust.md +69 -0
- package/seedgridKB/SeedGrid/Extensions/apikeys/Configuracao.md +88 -0
- package/seedgridKB/SeedGrid/Extensions/apikeys/Enums.md +33 -0
- package/seedgridKB/SeedGrid/Extensions/apikeys/Exemplos.md +121 -0
- package/seedgridKB/SeedGrid/Extensions/apikeys/Rust.md +126 -0
- package/seedgridKB/SeedGrid/Extensions/apikeys/Visao-geral.md +111 -0
- package/seedgridKB/SeedGrid/Extensions/audit/Configuracao-Rust.md +93 -0
- package/seedgridKB/SeedGrid/Extensions/audit/Configuracao.md +127 -0
- package/seedgridKB/SeedGrid/Extensions/audit/Enums.md +66 -0
- package/seedgridKB/SeedGrid/Extensions/audit/Exemplos.md +151 -0
- package/seedgridKB/SeedGrid/Extensions/audit/Rust.md +120 -0
- package/seedgridKB/SeedGrid/Extensions/audit/Visao-geral.md +114 -0
- package/seedgridKB/SeedGrid/Extensions/backup/Configuracao-Rust.md +136 -0
- package/seedgridKB/SeedGrid/Extensions/backup/Configuracao.md +319 -0
- package/seedgridKB/SeedGrid/Extensions/backup/Enums.md +131 -0
- package/seedgridKB/SeedGrid/Extensions/backup/Exemplos.md +210 -0
- package/seedgridKB/SeedGrid/Extensions/backup/Rust.md +135 -0
- package/seedgridKB/SeedGrid/Extensions/backup/Visao-geral.md +150 -0
- package/seedgridKB/SeedGrid/Extensions/billing/Configuracao-Rust.md +86 -0
- package/seedgridKB/SeedGrid/Extensions/billing/Configuracao.md +243 -0
- package/seedgridKB/SeedGrid/Extensions/billing/Enums.md +165 -0
- package/seedgridKB/SeedGrid/Extensions/billing/Exemplos.md +205 -0
- package/seedgridKB/SeedGrid/Extensions/billing/Rust.md +109 -0
- package/seedgridKB/SeedGrid/Extensions/billing/Visao-geral.md +181 -0
- package/seedgridKB/SeedGrid/Extensions/broker/Configuracao-Rust.md +40 -0
- package/seedgridKB/SeedGrid/Extensions/broker/Visao-geral.md +114 -0
- package/seedgridKB/SeedGrid/Extensions/cache/Configuracao-Rust.md +73 -0
- package/seedgridKB/SeedGrid/Extensions/cache/Configuracao.md +112 -0
- package/seedgridKB/SeedGrid/Extensions/cache/Enums.md +36 -0
- package/seedgridKB/SeedGrid/Extensions/cache/Exemplos.md +149 -0
- package/seedgridKB/SeedGrid/Extensions/cache/Rust.md +81 -0
- package/seedgridKB/SeedGrid/Extensions/cache/Visao-geral.md +90 -0
- package/seedgridKB/SeedGrid/Extensions/commons/Configuracao.md +107 -0
- package/seedgridKB/SeedGrid/Extensions/commons/Enums.md +105 -0
- package/seedgridKB/SeedGrid/Extensions/commons/Exemplos.md +141 -0
- package/seedgridKB/SeedGrid/Extensions/commons/Visao-geral.md +99 -0
- package/seedgridKB/SeedGrid/Extensions/exchange/Configuracao.md +122 -0
- package/seedgridKB/SeedGrid/Extensions/exchange/Enums.md +29 -0
- package/seedgridKB/SeedGrid/Extensions/exchange/Exemplos.md +82 -0
- package/seedgridKB/SeedGrid/Extensions/exchange/Visao-geral.md +118 -0
- package/seedgridKB/SeedGrid/Extensions/filemanagement/Configuracao-Rust.md +110 -0
- package/seedgridKB/SeedGrid/Extensions/filemanagement/Configuracao.md +157 -0
- package/seedgridKB/SeedGrid/Extensions/filemanagement/Exemplos.md +157 -0
- package/seedgridKB/SeedGrid/Extensions/filemanagement/Rust.md +70 -0
- package/seedgridKB/SeedGrid/Extensions/filemanagement/Visao-geral.md +88 -0
- package/seedgridKB/SeedGrid/Extensions/login-tenancy/Configuracao-Rust.md +124 -0
- package/seedgridKB/SeedGrid/Extensions/login-tenancy/Configuracao.md +195 -0
- package/seedgridKB/SeedGrid/Extensions/login-tenancy/Enums.md +71 -0
- package/seedgridKB/SeedGrid/Extensions/login-tenancy/Exemplos.md +149 -0
- package/seedgridKB/SeedGrid/Extensions/login-tenancy/Rust.md +139 -0
- package/seedgridKB/SeedGrid/Extensions/login-tenancy/Visao-geral.md +130 -0
- package/seedgridKB/SeedGrid/Extensions/notification/Configuracao.md +141 -0
- package/seedgridKB/SeedGrid/Extensions/notification/Enums.md +52 -0
- package/seedgridKB/SeedGrid/Extensions/notification/Exemplos.md +141 -0
- package/seedgridKB/SeedGrid/Extensions/notification/Visao-geral.md +113 -0
- package/seedgridKB/SeedGrid/Extensions/privacy/Configuracao-Rust.md +67 -0
- package/seedgridKB/SeedGrid/Extensions/privacy/Configuracao.md +94 -0
- package/seedgridKB/SeedGrid/Extensions/privacy/Enums.md +79 -0
- package/seedgridKB/SeedGrid/Extensions/privacy/Exemplos.md +172 -0
- package/seedgridKB/SeedGrid/Extensions/privacy/Rust.md +107 -0
- package/seedgridKB/SeedGrid/Extensions/privacy/Visao-geral.md +90 -0
- package/seedgridKB/SeedGrid/Extensions/realtime/Configuracao-Rust.md +72 -0
- package/seedgridKB/SeedGrid/Extensions/realtime/Configuracao.md +104 -0
- package/seedgridKB/SeedGrid/Extensions/realtime/Exemplos.md +104 -0
- package/seedgridKB/SeedGrid/Extensions/realtime/Rust.md +69 -0
- package/seedgridKB/SeedGrid/Extensions/realtime/Visao-geral.md +105 -0
- package/seedgridKB/SeedGrid/Extensions/resilience/Configuracao-Rust.md +68 -0
- package/seedgridKB/SeedGrid/Extensions/resilience/Configuracao.md +186 -0
- package/seedgridKB/SeedGrid/Extensions/resilience/Enums.md +96 -0
- package/seedgridKB/SeedGrid/Extensions/resilience/Exemplos.md +229 -0
- package/seedgridKB/SeedGrid/Extensions/resilience/Rust.md +80 -0
- package/seedgridKB/SeedGrid/Extensions/resilience/Visao-geral.md +112 -0
- package/seedgridKB/SeedGrid/Extensions/runtime/Configuracao-Rust.md +90 -0
- package/seedgridKB/SeedGrid/Extensions/runtime/Visao-geral.md +114 -0
- package/seedgridKB/SeedGrid/Extensions/security/Configuracao-Rust.md +327 -0
- package/seedgridKB/SeedGrid/Extensions/security/Configuracao.md +510 -0
- package/seedgridKB/SeedGrid/Extensions/security/Enums.md +95 -0
- package/seedgridKB/SeedGrid/Extensions/security/Exemplos.md +218 -0
- package/seedgridKB/SeedGrid/Extensions/security/Rust.md +203 -0
- package/seedgridKB/SeedGrid/Extensions/security/Visao-geral.md +131 -0
- package/seedgridKB/SeedGrid/Extensions/subdomain-tenancy/Configuracao-Rust.md +188 -0
- package/seedgridKB/SeedGrid/Extensions/subdomain-tenancy/Configuracao.md +345 -0
- package/seedgridKB/SeedGrid/Extensions/subdomain-tenancy/Enums.md +117 -0
- package/seedgridKB/SeedGrid/Extensions/subdomain-tenancy/Exemplos.md +205 -0
- package/seedgridKB/SeedGrid/Extensions/subdomain-tenancy/Rust.md +161 -0
- package/seedgridKB/SeedGrid/Extensions/subdomain-tenancy/Visao-geral.md +142 -0
- package/seedgridKB/SeedGrid/Extensions/whatsapp/Configuracao-Rust.md +75 -0
- package/seedgridKB/SeedGrid/Extensions/whatsapp/Configuracao.md +152 -0
- package/seedgridKB/SeedGrid/Extensions/whatsapp/Enums.md +198 -0
- package/seedgridKB/SeedGrid/Extensions/whatsapp/Exemplos.md +173 -0
- package/seedgridKB/SeedGrid/Extensions/whatsapp/Rust.md +83 -0
- package/seedgridKB/SeedGrid/Extensions/whatsapp/Visao-geral.md +99 -0
- package/seedgridKB/SeedGrid/Mapa-dos-repositorios.md +112 -0
- package/seedgridKB/SeedGrid/SeedGrid-components/Indice.md +323 -0
- package/seedgridKB/SeedGrid/SeedGrid-components/buttons/API.md +257 -0
- package/seedgridKB/SeedGrid/SeedGrid-components/buttons/Exemplos.md +307 -0
- package/seedgridKB/SeedGrid/SeedGrid-components/buttons/Visao-geral.md +51 -0
- package/seedgridKB/SeedGrid/SeedGrid-components/datatable/API.md +174 -0
- package/seedgridKB/SeedGrid/SeedGrid-components/datatable/Exemplos.md +236 -0
- package/seedgridKB/SeedGrid/SeedGrid-components/datatable/Visao-geral.md +76 -0
- package/seedgridKB/SeedGrid/SeedGrid-components/digits/API.md +339 -0
- package/seedgridKB/SeedGrid/SeedGrid-components/digits/Exemplos.md +311 -0
- package/seedgridKB/SeedGrid/SeedGrid-components/digits/Visao-geral.md +57 -0
- package/seedgridKB/SeedGrid/SeedGrid-components/editor/API.md +125 -0
- package/seedgridKB/SeedGrid/SeedGrid-components/editor/Exemplos.md +116 -0
- package/seedgridKB/SeedGrid/SeedGrid-components/editor/Visao-geral.md +86 -0
- package/seedgridKB/SeedGrid/SeedGrid-components/feedback-e-exibicao/API.md +490 -0
- package/seedgridKB/SeedGrid/SeedGrid-components/feedback-e-exibicao/Exemplos.md +544 -0
- package/seedgridKB/SeedGrid/SeedGrid-components/feedback-e-exibicao/Visao-geral.md +69 -0
- package/seedgridKB/SeedGrid/SeedGrid-components/fundamentos/API.md +113 -0
- package/seedgridKB/SeedGrid/SeedGrid-components/fundamentos/Exemplos.md +159 -0
- package/seedgridKB/SeedGrid/SeedGrid-components/fundamentos/Visao-geral.md +92 -0
- package/seedgridKB/SeedGrid/SeedGrid-components/gadgets/API.md +516 -0
- package/seedgridKB/SeedGrid/SeedGrid-components/gadgets/Exemplos.md +629 -0
- package/seedgridKB/SeedGrid/SeedGrid-components/gadgets/Visao-geral.md +80 -0
- package/seedgridKB/SeedGrid/SeedGrid-components/inputs-selecao/API.md +615 -0
- package/seedgridKB/SeedGrid/SeedGrid-components/inputs-selecao/Exemplos.md +384 -0
- package/seedgridKB/SeedGrid/SeedGrid-components/inputs-selecao/Visao-geral.md +111 -0
- package/seedgridKB/SeedGrid/SeedGrid-components/inputs-texto/API.md +661 -0
- package/seedgridKB/SeedGrid/SeedGrid-components/inputs-texto/Exemplos.md +312 -0
- package/seedgridKB/SeedGrid/SeedGrid-components/inputs-texto/Visao-geral.md +123 -0
- package/seedgridKB/SeedGrid/SeedGrid-components/layout/API.md +1090 -0
- package/seedgridKB/SeedGrid/SeedGrid-components/layout/Exemplos.md +1172 -0
- package/seedgridKB/SeedGrid/SeedGrid-components/layout/Visao-geral.md +98 -0
- package/seedgridKB/SeedGrid/SeedGrid-components/modulos/Visao-geral.md +98 -0
- package/seedgridKB/SeedGrid/SeedGrid-components/modulos/fe-apikeys.md +118 -0
- package/seedgridKB/SeedGrid/SeedGrid-components/modulos/fe-audit.md +88 -0
- package/seedgridKB/SeedGrid/SeedGrid-components/modulos/fe-backup.md +131 -0
- package/seedgridKB/SeedGrid/SeedGrid-components/modulos/fe-billing-platform.md +132 -0
- package/seedgridKB/SeedGrid/SeedGrid-components/modulos/fe-billing-user.md +120 -0
- package/seedgridKB/SeedGrid/SeedGrid-components/modulos/fe-login-tenancy.md +119 -0
- package/seedgridKB/SeedGrid/SeedGrid-components/modulos/fe-security.md +427 -0
- package/seedgridKB/SeedGrid/SeedGrid-components/modulos/fe-self-enter.md +104 -0
- package/seedgridKB/SeedGrid/SeedGrid-components/modulos/fe-subdomain-tenancy.md +110 -0
- package/seedgridKB/SeedGrid/SeedGrid-components/navegacao-e-overlay/API.md +490 -0
- package/seedgridKB/SeedGrid/SeedGrid-components/navegacao-e-overlay/Exemplos.md +561 -0
- package/seedgridKB/SeedGrid/SeedGrid-components/navegacao-e-overlay/Visao-geral.md +82 -0
- package/seedgridKB/SeedGrid/SeedGrid-components/pacotes/Visao-geral.md +68 -0
- package/seedgridKB/SeedGrid/SeedGrid-components/pacotes/fe-commons.md +61 -0
- package/seedgridKB/SeedGrid/SeedGrid-components/pacotes/fe-core.md +140 -0
- package/seedgridKB/SeedGrid/SeedGrid-components/pacotes/fe-playground.md +112 -0
- package/seedgridKB/SeedGrid/SeedGrid-components/pacotes/fe-theme.md +97 -0
- package/seedgridKB/SeedGrid/SeedGrid-components/providers/API.md +177 -0
- package/seedgridKB/SeedGrid/SeedGrid-components/providers/Exemplos.md +332 -0
- package/seedgridKB/SeedGrid/SeedGrid-components/providers/Visao-geral.md +106 -0
- package/seedgridKB/SeedGrid/SeedGrid-components/showcase.md +70 -0
- package/seedgridKB/SeedGrid/Toolkit/agents/arquiteto.md +53 -0
- package/seedgridKB/SeedGrid/Toolkit/agents/backend-java.md +45 -0
- package/seedgridKB/SeedGrid/Toolkit/agents/backend-rust.md +43 -0
- package/seedgridKB/SeedGrid/Toolkit/agents/frontend-react.md +41 -0
- package/seedgridKB/SeedGrid/Toolkit/agents/qa.md +44 -0
- package/seedgridKB/SeedGrid/Toolkit/agents/revisor.md +40 -0
- package/seedgridKB/SeedGrid/Toolkit/references/fluxo-de-trabalho.md +78 -0
- package/seedgridKB/SeedGrid/Toolkit/references/glossario.md +15 -0
- package/seedgridKB/SeedGrid/Toolkit/references/modos-shared-native.md +27 -0
- package/seedgridKB/SeedGrid/Toolkit/rules/backend-java-seedgrid.md +54 -0
- package/seedgridKB/SeedGrid/Toolkit/rules/coordenacao.md +39 -0
- package/seedgridKB/SeedGrid/Toolkit/rules/formato-entrega.md +29 -0
- package/seedgridKB/SeedGrid/Toolkit/rules/frontend-seedgrid.md +47 -0
- package/seedgridKB/SeedGrid/Toolkit/rules/personalizacao-local.md +22 -0
- package/seedgridKB/SeedGrid/Toolkit/skills/planejar-mudanca/SKILL.md +38 -0
- package/seedgridKB/SeedGrid/Toolkit/skills/revisar-codigo/SKILL.md +33 -0
- package/seedgridKB/SeedGrid/Toolkit/skills/revisar-codigo/references/checklist.md +25 -0
- package/seedgridKB/SeedGrid/Toolkit/skills/seedgrid-backend-crud/SKILL.md +29 -0
- package/seedgridKB/SeedGrid/Toolkit/skills/seedgrid-bump/SKILL.md +26 -0
- package/seedgridKB/SeedGrid/Toolkit/skills/seedgrid-crud/SKILL.md +221 -0
- package/seedgridKB/SeedGrid/Toolkit/skills/seedgrid-crud/agents/openai.yaml +4 -0
- package/seedgridKB/SeedGrid/Toolkit/skills/seedgrid-crud/references/checklist.md +31 -0
- package/seedgridKB/SeedGrid/Toolkit/skills/seedgrid-crud/references/patterns.md +185 -0
- package/seedgridKB/SeedGrid/Toolkit/skills/seedgrid-crud/references/routing.md +66 -0
- package/seedgridKB/SeedGrid/Toolkit/skills/seedgrid-new-screen/SKILL.md +56 -0
- package/seedgridKB/SeedGrid/Toolkit/skills/seedgrid-new-screen/agents/openai.yaml +4 -0
- package/seedgridKB/SeedGrid/Toolkit/skills/seedgrid-new-screen/references/checklist.md +32 -0
- package/seedgridKB/SeedGrid/Toolkit/skills/seedgrid-new-screen/references/steps.md +114 -0
- package/seedgridKB/SeedGrid/Toolkit/skills/seedgrid-review/SKILL.md +61 -0
- package/seedgridKB/SeedGrid/Toolkit/skills/validar-mudanca/SKILL.md +29 -0
- package/seedgridKB/SeedGrid/Toolkit/templates/decisao-arquitetura.md +29 -0
- package/seedgridKB/SeedGrid/Toolkit/templates/especificacao-tarefa.md +32 -0
- package/seedgridKB/SeedGrid/Toolkit/templates/relatorio-validacao.md +30 -0
- package/seedgridKB/SeedGrid/Versoes.md +64 -0
- package/seedgridKB/SeedGrid/Visao-geral.md +35 -0
- package/seedgridKB/manifest.json +142 -0
|
@@ -0,0 +1,510 @@
|
|
|
1
|
+
---
|
|
2
|
+
tags: [seedgrid, extension, security, configuracao]
|
|
3
|
+
fonte: java/seedgrid-quarkus-ext-security
|
|
4
|
+
branch: main
|
|
5
|
+
commit: 450735386e
|
|
6
|
+
analisado-em: 2026-10-14
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# security — Configuração (Quarkus)
|
|
10
|
+
|
|
11
|
+
Voltar para [[SeedGrid/Extensions/security/Visao-geral|Visão geral do security]] · [[SeedGrid/Extensions/security/Exemplos|Exemplos]] · [[SeedGrid/Extensions/security/Rust|Porte Rust]]
|
|
12
|
+
|
|
13
|
+
## 1. Cabeçalho
|
|
14
|
+
|
|
15
|
+
| Item | Valor |
|
|
16
|
+
|---|---|
|
|
17
|
+
| Prefixo principal | `seedgrid.security.*` |
|
|
18
|
+
| Outros prefixos lidos pelo código da extension | `seedgrid.show-dev-message`, `seedgrid.app.email-alert.window`, `seedgrid.ratelimit.<configKey>.*` (chaves declaradas pelo security, lidas pela lib resilience) |
|
|
19
|
+
| Mecanismo | `@ConfigMapping` (SmallRye) em interfaces do módulo **runtime** (15 mappings), `@ConfigProperty` (2 chaves), `ConfigProvider.getConfig().getOptionalValue(...)` (1 chave, repetida de um mapping), expressão de propriedade em `@Scheduled(cron = "{...}")` (1 chave, repetida de um mapping) |
|
|
20
|
+
| `@ConfigRoot` / `*BuildTimeConfig` | **Não existem.** O módulo `deployment` (`SecurityProcessor`) não lê nenhuma configuração. Nenhum `@IfBuildProperty` / `@LookupIfProperty` / `@UnlessBuildProperty` no security. |
|
|
21
|
+
| Fase | **Runtime** para todas as propriedades próprias |
|
|
22
|
+
| Defaults embarcados | `java/seedgrid-quarkus-ext-security/runtime/src/main/resources/META-INF/microprofile-config.properties` (ordinal 100). O `application.properties` do host (ordinal 250) e as variáveis de ambiente (ordinal 300) sobrescrevem. **Atenção:** vários valores desse arquivo diferem do `@WithDefault` da interface — o valor efetivo é o do arquivo. A coluna *Padrão* mostra o valor efetivo e, entre parênteses, o `@WithDefault` quando diferente. |
|
|
23
|
+
|
|
24
|
+
Classes de config (todas em `java/seedgrid-quarkus-ext-security/runtime/src/main/java/br/com/seedgrid/security/`):
|
|
25
|
+
|
|
26
|
+
| Classe | Prefixo |
|
|
27
|
+
|---|---|
|
|
28
|
+
| `configs/SecurityJwtConfig` | `seedgrid.security.jwt` |
|
|
29
|
+
| `configs/RefreshTokenConfig` | `seedgrid.security.refresh-token` |
|
|
30
|
+
| `configs/SecurityEncryptionConfig` | `seedgrid.security.encryption` |
|
|
31
|
+
| `configs/PasswordConfig` | `seedgrid.security.password` |
|
|
32
|
+
| `configs/TwoFactorConfig` | `seedgrid.security.2f` |
|
|
33
|
+
| `configs/SelfEnterConfig` | `seedgrid.security.self-enter` |
|
|
34
|
+
| `configs/SecurityMailerConfig` | `seedgrid.security.mailer` |
|
|
35
|
+
| `configs/SecurityFrontendConfig` | `seedgrid.security.frontend` |
|
|
36
|
+
| `configs/SecurityBootstrapConfig` | `seedgrid.security.bootstrap` |
|
|
37
|
+
| `configs/DefaultCompanyConfig` | `seedgrid.security.default-company` |
|
|
38
|
+
| `configs/FirstAdminUserConfig` | `seedgrid.security.first-admin-user` |
|
|
39
|
+
| `configs/AvatarConfig` | `seedgrid.security.avatar` |
|
|
40
|
+
| `configs/UserAttributesConfig` | `seedgrid.security.user.additional-attributes` |
|
|
41
|
+
| `configs/AccountManagementConfig` | `seedgrid.security.account` |
|
|
42
|
+
| `services/PermissionResolveService.RbacConfig` (interface aninhada) | `seedgrid.security.rbac` |
|
|
43
|
+
|
|
44
|
+
Convenções das tabelas:
|
|
45
|
+
- `…/security/` = `java/seedgrid-quarkus-ext-security/runtime/src/main/java/br/com/seedgrid/security/`
|
|
46
|
+
- `mp-config` = `java/seedgrid-quarkus-ext-security/runtime/src/main/resources/META-INF/microprofile-config.properties`
|
|
47
|
+
- Variáveis de ambiente: o `mp-config` declara expressões `${SEEDGRID_SECURITY_...:default}` — esses nomes são **lidos de fato** (Confirmado). Além disso vale a regra MicroProfile padrão (ex.: `seedgrid.security.jwt.issuer` → `SEEDGRID_SECURITY_JWT_ISSUER`). Onde o nome da expressão difere da regra padrão, isso é indicado.
|
|
48
|
+
- Propriedade com valor vazio (`${X:}`) é tratada pelo SmallRye como **ausente** → `Optional.empty()`.
|
|
49
|
+
- 🔒 = sensível; nunca versionar valor real.
|
|
50
|
+
- Grau de certeza: tudo **Confirmado** no código salvo marcação explícita (*Inferência* / *Não confirmado*).
|
|
51
|
+
|
|
52
|
+
Validação de startup (*Inferência* baseada no comportamento padrão do SmallRye Config para `@ConfigMapping`): todo método não-`Optional` e sem `@WithDefault` precisa ter valor ao subir; ausência derruba o boot. Como o `mp-config` fornece valor para quase todos, na prática só `seedgrid.security.encryption.key` e os três campos obrigatórios de `default-company` (que no `mp-config` apontam para variáveis de ambiente **sem default**) exigem ação do host.
|
|
53
|
+
|
|
54
|
+
---
|
|
55
|
+
|
|
56
|
+
## 2. Propriedades próprias da extension
|
|
57
|
+
|
|
58
|
+
### 2.1 JWT (`seedgrid.security.jwt.*`)
|
|
59
|
+
|
|
60
|
+
| Propriedade | Tipo | Valores aceitos | Padrão | Obrigatória | Comportamento | Uso | Relações | Fase | Origem |
|
|
61
|
+
|---|---|---|---|---|---|---|---|---|---|
|
|
62
|
+
| `seedgrid.security.jwt.issuer` | String | URL/texto livre | `https://seedgrid.com.br` (mp-config e `@WithDefault`) | Não | Vai no claim `iss` do access token e é comparado com igualdade exata ao validar | Emissão e verificação de JWT | Bridge `mp.jwt.verify.issuer=${seedgrid.security.jwt.issuer}` no mp-config | Runtime | Decl.: `…/security/configs/SecurityJwtConfig#issuer()`; consumo: `services/TokenService` (builder `.issuer`), `services/TokenVerifier#validateIssuer` |
|
|
63
|
+
| `seedgrid.security.jwt.kid` | Optional\<String\> | texto | `seedgrid-key` (mp-config; fallback em código `seedgrid-key`) | Não | Header `kid` do JWT RS256 | Emissão | — | Runtime | Decl.: `SecurityJwtConfig#kid()`; consumo: `TokenService` (`jwtConfig.kid().orElse("seedgrid-key")`) |
|
|
64
|
+
| `seedgrid.security.jwt.ttl` | Optional\<Duration\> | ISO-8601 (`PT8H`) | `PT8H` (mp-config; fallback em código 8 h) | Não | Expiração (`exp`) do access token | Emissão | Independente do `refresh-token.ttl` | Runtime | Decl.: `SecurityJwtConfig#ttl()`; consumo: `TokenService` (`jwtConfig.ttl().orElse(Duration.ofHours(8))`) |
|
|
65
|
+
| `seedgrid.security.jwt.private-key-location` 🔒 | Optional\<String\> | caminho de arquivo (absoluto/relativo) ou recurso de classpath, PEM `PRIVATE KEY` (PKCS#8) | `keys/private.pem` (mp-config; mesmo fallback em código) | Condicional — usada se `private-key-base64` vazio; o arquivo precisa existir | Tenta sistema de arquivos, depois classpath; falha → `IllegalStateException("Erro ao carregar chave privada RSA")` ao inicializar `RsaKeyProvider` | Assinatura RS256 | Alternativa a `private-key-base64` (base64 tem precedência) | Runtime | Decl.: `SecurityJwtConfig#privateKeyLocation()`; consumo: `configs/RsaKeyProvider#loadPrivateKey` |
|
|
66
|
+
| `seedgrid.security.jwt.private-key-base64` 🔒 | Optional\<String\> | Base64 do DER PKCS#8 (sem header PEM; espaços removidos) | vazio (= ausente) | Condicional (ver acima) | Se presente e não-branco, tem precedência sobre `private-key-location` | Assinatura RS256 | — | Runtime | Decl.: `SecurityJwtConfig#privateKeyBase64()`; consumo: `RsaKeyProvider#loadPrivateKey` |
|
|
67
|
+
| `seedgrid.security.jwt.public-key-location` | Optional\<String\> | caminho/classpath, PEM `PUBLIC KEY` (X.509) | `keys/public.pem` (mp-config; mesmo fallback em código) | Condicional — usada se `public-key-base64` vazio | Igual à privada | Verificação no `TokenVerifier` | Bridge `mp.jwt.verify.publickey.location=${seedgrid.security.jwt.public-key-location}` | Runtime | Decl.: `SecurityJwtConfig#publicKeyLocation()`; consumo: `RsaKeyProvider#loadPublicKey` |
|
|
68
|
+
| `seedgrid.security.jwt.public-key-base64` | Optional\<String\> | Base64 do DER X.509 | vazio | Condicional | Precedência sobre `public-key-location` | Verificação | **Não** há bridge para `mp.jwt.verify.publickey` (comentário no mp-config): quem usa base64 deve definir `MP_JWT_VERIFY_PUBLICKEY` diretamente | Runtime | Decl.: `SecurityJwtConfig#publicKeyBase64()`; consumo: `RsaKeyProvider#loadPublicKey` |
|
|
69
|
+
|
|
70
|
+
### 2.2 Refresh token (`seedgrid.security.refresh-token.*`)
|
|
71
|
+
|
|
72
|
+
| Propriedade | Tipo | Valores aceitos | Padrão | Obrigatória | Comportamento | Uso | Relações | Fase | Origem |
|
|
73
|
+
|---|---|---|---|---|---|---|---|---|---|
|
|
74
|
+
| `seedgrid.security.refresh-token.ttl` | Duration | ISO-8601 | `P30D` | Não | TTL deslizante: cada rotação emite token com nova janela (`expiresAt = now + ttl`) | Emissão/rotação de refresh token | — | Runtime | Decl.: `…/security/configs/RefreshTokenConfig#ttl()`; consumo: `services/RefreshTokenService#buildToken` |
|
|
75
|
+
| `seedgrid.security.refresh-token.reuse-grace-window` | Duration | ISO-8601; `PT0S` (ou negativo) desliga | `PT30S` | Não | Dentro da janela, reapresentar um token já rotacionado (não revogado, com `usedAt`) é tratado como corrida concorrente e emite outro token da mesma família, sem revogar; fora dela, reuso revoga a família | Detecção de reuso | Testes usam `PT0S` | Runtime | Decl.: `RefreshTokenConfig#reuseGraceWindow()`; consumo: `RefreshTokenService#isWithinReuseGraceWindow` |
|
|
76
|
+
|
|
77
|
+
### 2.3 Criptografia de segredos internos (`seedgrid.security.encryption.*`)
|
|
78
|
+
|
|
79
|
+
| Propriedade | Tipo | Valores aceitos | Padrão | Obrigatória | Comportamento | Uso | Relações | Fase | Origem |
|
|
80
|
+
|---|---|---|---|---|---|---|---|---|---|
|
|
81
|
+
| `seedgrid.security.encryption.key` 🔒 | String | Base64 de 32 bytes (AES-256) | — (não está no mp-config) | **Sim** | Chave AES-256-GCM (IV de 12 bytes) para cifrar segredos TOTP e a senha de bootstrap pendente (`pending_bootstrap_password`) | `SecretEncryptionService#encrypt/decrypt` | Independente de `seedgrid.privacy.*` (lib privacy) | Runtime | Decl.: `…/security/configs/SecurityEncryptionConfig#key()`; consumo: `services/SecretEncryptionService` (construtor) |
|
|
82
|
+
|
|
83
|
+
### 2.4 Política de senha (`seedgrid.security.password.*`)
|
|
84
|
+
|
|
85
|
+
Nenhuma tem `@WithDefault`. O mp-config fornece valores **permissivos** (comentário original: "lenient for tests"); um host que não os sobrescreva aceita senha de 1 caractere.
|
|
86
|
+
|
|
87
|
+
| Propriedade | Tipo | Valores aceitos | Padrão | Obrigatória | Comportamento | Uso | Relações | Fase | Origem |
|
|
88
|
+
|---|---|---|---|---|---|---|---|---|---|
|
|
89
|
+
| `seedgrid.security.password.min-size` | int | ≥ 0 | `1` (mp-config) | Sim no mapping; satisfeita pelo mp-config | Tamanho mínimo; o gerador de senha usa `max(min-size, nº de categorias exigidas)` | `PasswordService#validate`, `utils/PasswordGenerator#generate` | Senha do 1º admin é validada por esta política | Runtime | Decl.: `…/security/configs/PasswordConfig#minSize()`; consumo: `services/PasswordService`, `utils/PasswordGenerator` |
|
|
90
|
+
| `seedgrid.security.password.max-history` | int | ≥ 0; `0` desliga | `0` (mp-config) | idem | Bloqueia reutilizar as últimas N senhas | `PasswordHistoryService#isPasswordInHistory/addToHistory` | — | Runtime | Decl.: `PasswordConfig#maxHistory()`; consumo: `services/PasswordHistoryService` |
|
|
91
|
+
| `seedgrid.security.password.upper-case-required` | boolean | `true`/`false` | `false` (mp-config) | idem | Exige `[A-Z]` | Validação e geração | — | Runtime | Decl.: `PasswordConfig#upperCaseRequired()`; consumo: `PasswordService`, `PasswordGenerator` |
|
|
92
|
+
| `seedgrid.security.password.lower-case-required` | boolean | `true`/`false` | `false` (mp-config) | idem | Exige `[a-z]` | Validação e geração | — | Runtime | Decl.: `PasswordConfig#lowerCaseRequired()`; consumo: `PasswordService`, `PasswordGenerator` |
|
|
93
|
+
| `seedgrid.security.password.special-character-required` | boolean | `true`/`false` | `false` (mp-config) | idem | Exige um de `!@#$%^&*(),.?":{}\|<>` | Validação e geração | — | Runtime | Decl.: `PasswordConfig#specialCharacterRequired()`; consumo: `PasswordService`, `PasswordGenerator` |
|
|
94
|
+
| `seedgrid.security.password.prohibits-repeated-characters-in-sequence` | boolean | `true`/`false` | `false` (mp-config) | idem | Rejeita dois caracteres iguais consecutivos | Validação | — | Runtime | Decl.: `PasswordConfig#prohibitsRepeatedCharactersInSequence()`; consumo: `PasswordService#validate` |
|
|
95
|
+
| `seedgrid.security.password.expiration-days` | int | ≥ 0; `0` = não expira | `0` (mp-config) | idem | Calcula `passwordExpiresAt = now + N dias` | `PasswordHistoryService#calculatePasswordExpiration` | — | Runtime | Decl.: `PasswordConfig#expirationDays()`; consumo: `PasswordHistoryService` |
|
|
96
|
+
|
|
97
|
+
### 2.5 2FA (`seedgrid.security.2f.*`)
|
|
98
|
+
|
|
99
|
+
| Propriedade | Tipo | Valores aceitos | Padrão | Obrigatória | Comportamento | Uso | Relações | Fase | Origem |
|
|
100
|
+
|---|---|---|---|---|---|---|---|---|---|
|
|
101
|
+
| `seedgrid.security.2f.enabled` | boolean | `true`/`false` | **`true`** (mp-config; `@WithDefault` `false`) | Não | `false`: `/2f/enable` responde 400 "2FA is disabled" e o login não inicia desafio 2FA | Login e endpoints `/2f/*` | — | Runtime | Decl.: `…/security/configs/TwoFactorConfig#enabled()`; consumo: `services/AuthService` (login), `controllers/TwoFactorController#enable2FA`, `services/TwoFactorService` |
|
|
102
|
+
| `seedgrid.security.2f.allowed-methods` | List\<String\> | `EMAIL`, `TOTP`, `WHATSAPP` (códigos das `TwoFactorStrategy` registradas; normalizados `trim().toUpperCase()`; ver [[SeedGrid/Extensions/security/Enums#TwoFactorMethodType\|TwoFactorMethodType]] — `BACKUP_CODE` existe no enum mas não tem estratégia) | `EMAIL,TOTP` | Não | Interseção com as estratégias disponíveis e com `canEnroll(user)` define o que o usuário pode ativar | `TwoFactorController#getAllowedMethods/isAllowedMethod` | `WHATSAPP` exige `whatsapp.channel-id` | Runtime | Decl.: `TwoFactorConfig#allowedMethods()`; consumo: `controllers/TwoFactorController` |
|
|
103
|
+
| `seedgrid.security.2f.totp.issuer` | String | texto | `SeedGrid` | Não | Issuer na URL `otpauth://` e no QR | Setup TOTP | — | Runtime | Decl.: `TwoFactorConfig.Totp#issuer()`; consumo: `services/TwoFactorService` |
|
|
104
|
+
| `seedgrid.security.2f.totp.digits` | int | ex.: 6 | `6` | Não | Dígitos do código TOTP | Setup e verificação TOTP | — | Runtime | Decl.: `TwoFactorConfig.Totp#digits()`; consumo: `TwoFactorService`, `spi/impl/TotpTwoFactorStrategy` |
|
|
105
|
+
| `seedgrid.security.2f.totp.period` | int | segundos | `30` | Não | Período do código | Setup e verificação TOTP | — | Runtime | Decl.: `TwoFactorConfig.Totp#period()`; consumo: idem |
|
|
106
|
+
| `seedgrid.security.2f.totp.window` | int | ≥ 0 | `1` | Não | Tolerância de clock skew (períodos antes/depois) | Verificação TOTP | — | Runtime | Decl.: `TwoFactorConfig.Totp#window()`; consumo: `TwoFactorService`, `TotpTwoFactorStrategy` |
|
|
107
|
+
| `seedgrid.security.2f.otp-qrcode.branding.enabled` | boolean | `true`/`false` | `false` | Não | Sobrepõe logo no QR code | Setup TOTP com `includeQrImage=true` | Requer `otp-qrcode.logo` | Runtime | Decl.: `TwoFactorConfig.OtpQrCode.Branding#enabled()` (`@WithName("otp-qrcode")`); consumo: `TwoFactorService` → `utils/TotpUtil#generateQrCodeBase64` |
|
|
108
|
+
| `seedgrid.security.2f.otp-qrcode.logo` | Optional\<String\> | `classpath:...` ou caminho de arquivo | — | Condicional (só com branding) | Caminho do logo | idem | — | Runtime | Decl.: `TwoFactorConfig.OtpQrCode#logo()`; consumo: `TwoFactorService` |
|
|
109
|
+
| `seedgrid.security.2f.otp-qrcode.size` | int | pixels | `256` | Não | Largura/altura da imagem QR | idem | — | Runtime | Decl.: `TwoFactorConfig.OtpQrCode#size()`; consumo: `TwoFactorService`, `TwoFactorController` |
|
|
110
|
+
| `seedgrid.security.2f.verify.max-attempts` | int | ≥ 1 | `5` | Não | Ao exceder, a sessão 2FA (tempToken) é removida e a verificação falha | `TwoFactorService` (verify) | Somado ao rate-limit `2fa-verify` | Runtime | Decl.: `TwoFactorConfig.Verify#maxAttempts()`; consumo: `services/TwoFactorService` |
|
|
111
|
+
| `seedgrid.security.2f.session.ttl` | Duration | ISO-8601 | `PT5M` | Não | Validade do `tempToken` (sessão 2FA em cache) | `TwoFactorService` | — | Runtime | Decl.: `TwoFactorConfig.Session#ttl()`; consumo: `TwoFactorService` |
|
|
112
|
+
| `seedgrid.security.2f.email.code-ttl` | Duration | ISO-8601 | `PT5M` | Não | Validade do código por e-mail | Estratégia EMAIL | — | Runtime | Decl.: `TwoFactorConfig.Email#codeTtl()`; consumo: `spi/impl/EmailTwoFactorStrategy` |
|
|
113
|
+
| `seedgrid.security.2f.backup-codes.count` | int | ≥ 1 | `10` | Não | Quantidade de backup codes gerados | `BackupCodeService` | — | Runtime | Decl.: `TwoFactorConfig.BackupCodes#count()`; consumo: `services/BackupCodeService` |
|
|
114
|
+
| `seedgrid.security.2f.backup-codes.length` | int | ≥ 1 | `6` | Não | Tamanho de cada backup code | `BackupCodeService` | — | Runtime | Decl.: `TwoFactorConfig.BackupCodes#length()`; consumo: `BackupCodeService` |
|
|
115
|
+
| `seedgrid.security.2f.whatsapp.channel-id` | Optional\<String\> | id do canal/instância do provedor WhatsApp | vazio (mp-config `${SEEDGRID_SECURITY_2F_WHATSAPP_CHANNEL_ID:}`) | Condicional — necessário para usar `WHATSAPP` | Sem valor, a ativação de WHATSAPP responde "WHATSAPP 2FA is not configured. Define seedgrid.security.2f.whatsapp.channel-id." | Envio via `WhatsAppApi` | Depende da extension whatsapp (`seedgrid.whatsapp.api`) | Runtime | Decl.: `TwoFactorConfig.Whatsapp#channelId()`; consumo: `spi/impl/WhatsappTwoFactorStrategy`, `TwoFactorController` |
|
|
116
|
+
| `seedgrid.security.2f.whatsapp.code-ttl` | Duration | ISO-8601 | `PT5M` | Não | Validade do código por WhatsApp | Estratégia WHATSAPP | — | Runtime | Decl.: `TwoFactorConfig.Whatsapp#codeTtl()`; consumo: `WhatsappTwoFactorStrategy` |
|
|
117
|
+
|
|
118
|
+
### 2.6 Self-enter — auto-cadastro e convites (`seedgrid.security.self-enter.*`)
|
|
119
|
+
|
|
120
|
+
| Propriedade | Tipo | Valores aceitos | Padrão | Obrigatória | Comportamento | Uso | Relações | Fase | Origem |
|
|
121
|
+
|---|---|---|---|---|---|---|---|---|---|
|
|
122
|
+
| `seedgrid.security.self-enter.enabled` | boolean | `true`/`false` | `false` | Não | `false`: `SelfEnterDisabledFilter` (`@PreMatching`) responde 404 para `/self-enter*`, `/public/self-enter*` (também com prefixo `/api`) e `SelfEnterOpenApiFilter` remove as rotas/tag do OpenAPI; o job de limpeza não roda | Todo o módulo self-enter | Pré-condição de `public-enabled`/`invite-enabled`/`cleanup.enabled` | Runtime | Decl.: `…/security/configs/SelfEnterConfig#enabled()`; consumo: `filters/SelfEnterDisabledFilter` e `openapi/SelfEnterOpenApiFilter` (via `ConfigProvider.getOptionalValue`, fallback `false`), `services/SelfEnterService`, `controllers/SelfEnter*Controller`, `jobs/EntryRequestCleanupJob` |
|
|
123
|
+
| `seedgrid.security.self-enter.public-enabled` | boolean | `true`/`false` | `true` | Não | Libera o signup público (`POST /public/self-enter/requests` e o link público) | `SelfEnterService`, `SelfEnterController#publicLink`, `SelfEnterPublicController` | Só vale com `enabled=true` | Runtime | Decl.: `SelfEnterConfig#publicEnabled()`; consumo: idem |
|
|
124
|
+
| `seedgrid.security.self-enter.invite-enabled` | boolean | `true`/`false` | `true` | Não | Libera convites (`/self-enter/invitations`, `/public/self-enter/invitations/{token}`) | idem | Só vale com `enabled=true` | Runtime | Decl.: `SelfEnterConfig#inviteEnabled()`; consumo: idem |
|
|
125
|
+
| `seedgrid.security.self-enter.invite-needs-approval` | boolean | `true`/`false` | `true` | Não | `false`: convite aceito já cria o usuário (quem convidou é aprovador implícito). Não afeta o signup público, que sempre exige aprovação | `SelfEnterService` | — | Runtime | Decl.: `SelfEnterConfig#inviteNeedsApproval()`; consumo: `SelfEnterService` |
|
|
126
|
+
| `seedgrid.security.self-enter.request-ttl` | Duration | ISO-8601 | `PT48H` | Não | Validade da solicitação de entrada (confirmar e-mail + aprovação) | `SelfEnterService` | — | Runtime | Decl.: `SelfEnterConfig#requestTtl()`; consumo: `SelfEnterService` |
|
|
127
|
+
| `seedgrid.security.self-enter.invite-ttl` | Duration | ISO-8601 | `PT168H` | Não | Validade do convite; também enviada em horas no e-mail | `SelfEnterService` | — | Runtime | Decl.: `SelfEnterConfig#inviteTtl()`; consumo: `SelfEnterService` |
|
|
128
|
+
| `seedgrid.security.self-enter.email-token-ttl` | Duration | ISO-8601 | `PT30M` | Não | Validade do código OTP de confirmação de e-mail | `SelfEnterService` | — | Runtime | Decl.: `SelfEnterConfig#emailTokenTtl()`; consumo: `SelfEnterService` |
|
|
129
|
+
| `seedgrid.security.self-enter.default-role` | String | nome **exato** (case-sensitive) de uma role **global** (`company_id IS NULL`) | — (sem padrão) | **Sim, quando `self-enter.enabled=true`**: o boot falha (`SelfEnterConfigValidator`, `IllegalStateException`) se estiver ausente ou em branco. Só presença é validada; a existência da role não é checada no boot | Usada **só** quando nem o convite nem a aprovação trazem roles (`SelfEnterService#resolveApprovalRoles`). Busca por `RoleRepository#findByName` (`r.name = :name AND r.companyId IS NULL`): role criada por conta/empresa **não** é encontrada. Role inexistente (ou propriedade ausente) → `InvalidEntryRequestStatusException` (HTTP 422), sem fallback; role de integração → `UserRoleNotAllowedException` (HTTP 403). Em conta cliente isolada (`companyId` presente, mais de uma empresa e não é a plataforma) a default-role **não** passa por `requireAssignableInCompany` (as roles do convite exigem role da própria conta ou global `is_system`) e vira role da membership; fora disso vira role global do usuário. Como não há padrão, quem opera escolhe a role: se for uma role privilegiada, convite sem roles com `invite-needs-approval=false` cria um usuário com esses privilégios automaticamente — prefira uma role de menor privilégio | Aprovação de entry request (manual ou auto-aprovação do convite) | Roles do convite/aprovação (por `publicId`) têm precedência; `invite-needs-approval` | Runtime | Decl.: `SelfEnterConfig#defaultRole()`; consumo: `services/SelfEnterService#resolveApprovalRoles`, `repositories/RoleRepository#findByName` |
|
|
130
|
+
| `seedgrid.security.self-enter.cleanup.enabled` | boolean | `true`/`false` | `true` | Não | Liga o job que expira solicitações antigas e purga finalizadas (todos os tenants) | `EntryRequestCleanupJob#cleanup` | Exige `self-enter.enabled=true` | Runtime | Decl.: `SelfEnterConfig.Cleanup#enabled()`; consumo: `jobs/EntryRequestCleanupJob` |
|
|
131
|
+
| `seedgrid.security.self-enter.cleanup.cron` | String | cron Quartz (6–7 campos) | `0 */10 * * * ?` | Não | Agenda do job (`@Scheduled(cron = "{seedgrid.security.self-enter.cleanup.cron}")`, execução concorrente `SKIP`) | Scheduler Quarkus | *Inferência*: o default do `@WithDefault` é visível à expressão do `@Scheduled` porque o SmallRye registra defaults de mappings como fonte de config | Runtime (lido ao iniciar o scheduler) | Decl.: `SelfEnterConfig.Cleanup#cron()`; consumo: `EntryRequestCleanupJob` (anotação) |
|
|
132
|
+
| `seedgrid.security.self-enter.cleanup.purge-after` | Duration | ISO-8601 | `PT168H` | Não | Idade após a qual solicitações APPROVED/REJECTED/EXPIRED são apagadas | Job de limpeza | — | Runtime | Decl.: `SelfEnterConfig.Cleanup#purgeAfter()`; consumo: `EntryRequestCleanupJob` |
|
|
133
|
+
| `seedgrid.security.self-enter.email.confirm-subject` | String | texto | `Confirme seu e-mail` | Não | Assunto do e-mail com código de confirmação | `SelfEnterService` | — | Runtime | Decl.: `SelfEnterConfig.Email#confirmSubject()`; consumo: `SelfEnterService` |
|
|
134
|
+
| `seedgrid.security.self-enter.email.invite-subject` | String | texto | `Voce recebeu um convite para cadastro` | Não | Assunto do e-mail de convite | `SelfEnterService` | — | Runtime | Decl.: `SelfEnterConfig.Email#inviteSubject()`; consumo: `SelfEnterService` |
|
|
135
|
+
|
|
136
|
+
### 2.7 E-mail / SMTP (`seedgrid.security.mailer.*`)
|
|
137
|
+
|
|
138
|
+
Os e-mails usam o mailer **nomeado** `@MailerName("security")`. As chaves SMTP abaixo só chegam ao Quarkus pelo *bridge* do mp-config (`quarkus.mailer."security".*=${seedgrid.security.mailer.*}`); o código Java só lê `from`.
|
|
139
|
+
|
|
140
|
+
| Propriedade | Tipo | Valores aceitos | Padrão | Obrigatória | Comportamento | Uso | Relações | Fase | Origem |
|
|
141
|
+
|---|---|---|---|---|---|---|---|---|---|
|
|
142
|
+
| `seedgrid.security.mailer.from` | String | e-mail | `noreply@example.com` (mp-config) | Sim no mapping; satisfeita pelo mp-config (sobrescrever em produção) | `From` de todos os e-mails do `DefaultEmailService` | Confirmação, reset, boas-vindas, self-enter, 2FA | Bridge `quarkus.mailer."security".from` | Runtime | Decl.: `…/security/configs/SecurityMailerConfig#from()`; consumo: `spi/impl/DefaultEmailService` |
|
|
143
|
+
| `seedgrid.security.mailer.host` | Optional\<String\> | hostname | `smtp.gmail.com` (mp-config) | Não | Efeito só pela ponte (`quarkus.mailer."security".host`) | SMTP | `quarkus.mailer."security".host` | Runtime | Decl.: `SecurityMailerConfig#host()`; consumo: ponte no mp-config (o Java não lê) |
|
|
144
|
+
| `seedgrid.security.mailer.port` | Optional\<Integer\> | porta | `587` (mp-config) | Não | idem | SMTP | `quarkus.mailer."security".port` | Runtime | Decl.: `SecurityMailerConfig#port()`; bridge |
|
|
145
|
+
| `seedgrid.security.mailer.start-tls` | Optional\<String\> | `DISABLED`/`OPTIONAL`/`REQUIRED` (valores do `quarkus.mailer.start-tls`; o javadoc da interface cita `NEVER`, que não é valor do Quarkus) | `REQUIRED` (mp-config) | Não | idem | SMTP | `quarkus.mailer."security".start-tls` | Runtime | Decl.: `SecurityMailerConfig#startTls()`; bridge |
|
|
146
|
+
| `seedgrid.security.mailer.username` 🔒 | Optional\<String\> | texto | vazio | Não | idem | SMTP AUTH | `quarkus.mailer."security".username` | Runtime | Decl.: `SecurityMailerConfig#username()`; bridge |
|
|
147
|
+
| `seedgrid.security.mailer.password` 🔒 | Optional\<String\> | texto | vazio | Não | idem | SMTP AUTH | `quarkus.mailer."security".password` | Runtime | Decl.: `SecurityMailerConfig#password()`; bridge |
|
|
148
|
+
| `seedgrid.security.mailer.auth-methods` | Optional\<String\> | métodos SASL separados por espaço | `PLAIN LOGIN` (mp-config) | Não | Evita que o Vert.x escolha XOAUTH2 (Gmail) com senha comum | SMTP AUTH | `quarkus.mailer."security".auth-methods` | Runtime | Decl.: `SecurityMailerConfig#authMethods()`; bridge |
|
|
149
|
+
|
|
150
|
+
Como funciona a ponte: o mp-config define `quarkus.mailer."security".<campo>=${seedgrid.security.mailer.<campo>}` para `from`, `host`, `port`, `start-tls`, `username`, `password` e `auth-methods`. Por isso essas chaves `seedgrid.security.mailer.*` funcionam, mas **só enquanto o host não redefinir** a `quarkus.mailer."security".<campo>` correspondente (que passa a valer no lugar). Usuário/senha vazios resultam em SMTP sem autenticação — a suíte de testes sobe assim, com `quarkus.mailer."security".mock=true`.
|
|
151
|
+
|
|
152
|
+
### 2.8 URLs do frontend (`seedgrid.security.frontend.*`)
|
|
153
|
+
|
|
154
|
+
Todas são `String` não-`Optional`; `SecurityLinkBuilder` ainda valida em uso: vazio → `IllegalStateException("Missing required property: …")`, path sem `/` inicial → `IllegalStateException("Property must start with '/': …")`. A barra final de `base-url` é removida.
|
|
155
|
+
|
|
156
|
+
| Propriedade | Tipo | Valores aceitos | Padrão | Obrigatória | Comportamento | Uso | Relações | Fase | Origem |
|
|
157
|
+
|---|---|---|---|---|---|---|---|---|---|
|
|
158
|
+
| `seedgrid.security.frontend.base-url` | String | origem `http(s)://host[:porta]` | `http://localhost:3000` (mp-config) | Sim (satisfeita pelo mp-config; sobrescrever em produção) | Prefixo de todos os links dos e-mails | `SecurityLinkBuilder` | Junta com cada `*-path` | Runtime | Decl.: `…/security/configs/SecurityFrontendConfig#baseUrl()`; consumo: `services/SecurityLinkBuilder#resolveBaseUrl` |
|
|
159
|
+
| `seedgrid.security.frontend.login-path` | String | começa com `/` | `/login` | idem | Monta a URL de login em `SecurityLinkBuilder#buildLoginUrl` (bean público; `DefaultEmailService#buildLoginLink` a expõe a subclasses). **Nenhum e-mail embutido usa este link hoje** — só tem efeito se o host/SPI chamar `buildLoginUrl()` | `SecurityLinkBuilder#buildLoginUrl` | — | Runtime | Decl.: `SecurityFrontendConfig#loginPath()` |
|
|
160
|
+
| `seedgrid.security.frontend.password-reset-path` | String | começa com `/` | `/auth/forgot-password/confirm` | idem | Link de reset, com `?token=` | `buildPasswordResetUrl` | — | Runtime | Decl.: `SecurityFrontendConfig#passwordResetPath()` |
|
|
161
|
+
| `seedgrid.security.frontend.email-confirmation-path` | String | começa com `/` | `/auth/confirm-email` | idem | Link de confirmação de e-mail, com `?token=` | `buildEmailConfirmationUrl` | — | Runtime | Decl.: `SecurityFrontendConfig#emailConfirmationPath()` |
|
|
162
|
+
| `seedgrid.security.frontend.welcome-path` | String | começa com `/` | `/auth/welcome` | idem | Link do e-mail de boas-vindas (1º admin / usuários criados), com `?token=` | `buildWelcomeUrl` | — | Runtime | Decl.: `SecurityFrontendConfig#welcomePath()` |
|
|
163
|
+
| `seedgrid.security.frontend.self-enter-path` | String | começa com `/` | `/auth/self-enter` (mp-config) | idem | Link do convite de self-enter, com `?token=` | `buildSelfEnterInviteUrl` | Os testes e o README usam `/auth/self-enter/invitation` | Runtime | Decl.: `SecurityFrontendConfig#selfEnterPath()` |
|
|
164
|
+
|
|
165
|
+
### 2.9 Bootstrap: empresa default e primeiro admin
|
|
166
|
+
|
|
167
|
+
| Propriedade | Tipo | Valores aceitos | Padrão | Obrigatória | Comportamento | Uso | Relações | Fase | Origem |
|
|
168
|
+
|---|---|---|---|---|---|---|---|---|---|
|
|
169
|
+
| `seedgrid.security.bootstrap.enabled` | boolean | `true`/`false` | `true` | Não | No `StartupEvent`: cria a empresa default (se não existir pelo CNPJ), vincula usuários sem empresa (se só houver 1 empresa) e cria o 1º admin. **Deve ser `false` em host database-per-tenant** (subdomain-tenancy), senão o boot cai | `FirstAdminBootstrapService#onStart` | Controla `default-company.*` e `first-admin-user.*` no boot | Runtime | Decl.: `…/security/configs/SecurityBootstrapConfig#enabled()`; consumo: `services/FirstAdminBootstrapService` |
|
|
170
|
+
| `seedgrid.security.default-company.cnpj` | String | CNPJ (pontuação removida) | — (mp-config `${SEEDGRID_SECURITY_DEFAULT_COMPANY_CNPJ}` **sem default**) | **Sim** — mesmo com bootstrap desligado (*Inferência*: validação do mapping; o teste `BootstrapDisabledProfile` também define) | Identifica a "empresa-plataforma": criada no bootstrap; excluída do seletor de empresas do cliente; define quem é usuário de plataforma (`@PlatformScope`) | Bootstrap, `AuthService`, `PlatformScopeFilter`, `PlatformCompanyService` | — | Runtime | Decl.: `…/security/configs/DefaultCompanyConfig#cnpj()`; consumo: `FirstAdminBootstrapService#ensureDefaultCompany`, `services/AuthService`, `filters/PlatformScopeFilter`, `services/PlatformCompanyService` |
|
|
171
|
+
| `seedgrid.security.default-company.corporate-name` | String | texto | — (env sem default) | **Sim** | Razão social da empresa criada | Bootstrap | — | Runtime | Decl.: `DefaultCompanyConfig#corporateName()`; consumo: `FirstAdminBootstrapService#createDefaultCompany` |
|
|
172
|
+
| `seedgrid.security.default-company.trade-name` | String | texto | — (env sem default) | **Sim** | Nome fantasia | Bootstrap | — | Runtime | Decl.: `DefaultCompanyConfig#tradeName()`; consumo: idem |
|
|
173
|
+
| `seedgrid.security.default-company.addr-street` | Optional\<String\> | texto | vazio | Não | Endereço da empresa criada (trim → null) | Bootstrap | — | Runtime | Decl.: `DefaultCompanyConfig#addrStreet()`; consumo: `createDefaultCompany` |
|
|
174
|
+
| `seedgrid.security.default-company.addr-number` | Optional\<String\> | texto | vazio | Não | idem | Bootstrap | — | Runtime | Decl.: `DefaultCompanyConfig#addrNumber()` |
|
|
175
|
+
| `seedgrid.security.default-company.addr-complement` | Optional\<String\> | texto | vazio | Não | idem | Bootstrap | — | Runtime | Decl.: `DefaultCompanyConfig#addrComplement()` |
|
|
176
|
+
| `seedgrid.security.default-company.addr-postal-code` | Optional\<String\> | texto | vazio | Não | idem | Bootstrap | — | Runtime | Decl.: `DefaultCompanyConfig#addrPostalCode()` |
|
|
177
|
+
| `seedgrid.security.default-company.addr-city` | Optional\<String\> | texto | vazio | Não | idem | Bootstrap | — | Runtime | Decl.: `DefaultCompanyConfig#addrCity()` |
|
|
178
|
+
| `seedgrid.security.default-company.addr-state` | Optional\<String\> | sigla de UF; `StateEnum.valueOf(valor.toUpperCase())` — valor inválido lança `IllegalArgumentException` no bootstrap | vazio | Não | idem | Bootstrap | — | Runtime | Decl.: `DefaultCompanyConfig#addrState()` |
|
|
179
|
+
| `seedgrid.security.default-company.addr-district` | Optional\<String\> | texto | vazio | Não | idem | Bootstrap | — | Runtime | Decl.: `DefaultCompanyConfig#addrDistrict()` |
|
|
180
|
+
| `seedgrid.security.default-company.addr-phone` | Optional\<String\> | texto | vazio | Não | idem | Bootstrap | — | Runtime | Decl.: `DefaultCompanyConfig#addrPhone()` |
|
|
181
|
+
| `seedgrid.security.default-company.rep-first-name` | Optional\<String\> | texto | vazio | Não | Representante legal | Bootstrap | — | Runtime | Decl.: `DefaultCompanyConfig#repFirstName()` |
|
|
182
|
+
| `seedgrid.security.default-company.rep-last-name` | Optional\<String\> | texto | vazio | Não | idem | Bootstrap | — | Runtime | Decl.: `DefaultCompanyConfig#repLastName()` |
|
|
183
|
+
| `seedgrid.security.default-company.rep-cpf` | Optional\<String\> | CPF | vazio | Não | idem (PII) | Bootstrap | — | Runtime | Decl.: `DefaultCompanyConfig#repCpf()` |
|
|
184
|
+
| `seedgrid.security.default-company.rep-birth-date` | Optional\<String\> | data ISO `yyyy-MM-dd` (`LocalDate.parse`) | vazio | Não | idem | Bootstrap | — | Runtime | Decl.: `DefaultCompanyConfig#repBirthDate()` |
|
|
185
|
+
| `seedgrid.security.default-company.rep-phone` | Optional\<String\> | texto | vazio | Não | idem | Bootstrap | — | Runtime | Decl.: `DefaultCompanyConfig#repPhone()` |
|
|
186
|
+
| `seedgrid.security.default-company.rep-whatsapp` | Optional\<String\> | texto | vazio | Não | idem | Bootstrap | — | Runtime | Decl.: `DefaultCompanyConfig#repWhatsapp()` |
|
|
187
|
+
| `seedgrid.security.default-company.rep-email` | Optional\<String\> | e-mail | vazio | Não | idem | Bootstrap | — | Runtime | Decl.: `DefaultCompanyConfig#repEmail()` |
|
|
188
|
+
| `seedgrid.security.first-admin-user.email` | Optional\<String\> | e-mail (normalizado lower-case) | vazio | Não | Vazio → 1º admin não é criado. Se o usuário já existe e não confirmou o e-mail, reenvia boas-vindas. Só cria se a tabela `users` estiver vazia; recebe role `ADMIN`, `root=true`, troca de senha obrigatória | Bootstrap | Requer `bootstrap.enabled=true`, role `ADMIN` semeada (V204), mailer | Runtime | Decl.: `…/security/configs/FirstAdminUserConfig#email()`; consumo: `FirstAdminBootstrapService#onStart` |
|
|
189
|
+
| `seedgrid.security.first-admin-user.name` | Optional\<String\> | texto | vazio (fallback em código: `Administrador`) | Não | Nome do 1º admin | Bootstrap | — | Runtime | Decl.: `FirstAdminUserConfig#name()`; consumo: `FirstAdminBootstrapService#resolveName` |
|
|
190
|
+
| `seedgrid.security.first-admin-user.whatsapp` | Optional\<String\> | texto | vazio (→ `""`) | Não | WhatsApp do 1º admin | Bootstrap | — | Runtime | Decl.: `FirstAdminUserConfig#whatsapp()` |
|
|
191
|
+
| `seedgrid.security.first-admin-user.initial-password` 🔒 | Optional\<String\> | senha que passe na política | vazio (→ senha gerada por `PasswordGenerator`) | Não | Validada pela política de senha; guardada cifrada (`encryption.key`) até a troca e enviada no e-mail de boas-vindas | Bootstrap | `password.*`, `encryption.key` | Runtime | Decl.: `FirstAdminUserConfig#initialPassword()`; consumo: `FirstAdminBootstrapService#resolvePassword` |
|
|
192
|
+
|
|
193
|
+
### 2.10 Avatar (`seedgrid.security.avatar.*`)
|
|
194
|
+
|
|
195
|
+
O mapa por backend é repassado ao `FileStorageRegistry` da lib filemanagement (`fileStorageRegistry.get(storageType, config)`), com as chaves internas `base-path`, `bucket`, `region`, `access-key`, `secret-key`, `endpoint`, `connection-string`, `container`, `account-name`, `account-key`, `root-folder-id`, `credentials-file`, `credentials-json`, `client-id`, `client-secret`, `tenant-id`, `root-folder-path`, `project-id`. Validação de obrigatoriedade por backend fica na filemanagement (não confirmada aqui — ver [[SeedGrid/Extensions/filemanagement/Configuracao|Configuração da filemanagement]]).
|
|
196
|
+
|
|
197
|
+
| Propriedade | Tipo | Valores aceitos | Padrão | Obrigatória | Comportamento | Uso | Relações | Fase | Origem |
|
|
198
|
+
|---|---|---|---|---|---|---|---|---|---|
|
|
199
|
+
| `seedgrid.security.avatar.storage` | String | `filesystem`, `s3`, `minio`, `azure-blob`, `google-drive`, `onedrive`, `gcs` (case-insensitive); outro → `IllegalArgumentException("Unknown storage type")` | `filesystem` | Não | Backend onde o avatar é gravado | Upload de avatar de usuário e default | Seleciona o grupo de chaves abaixo | Runtime | Decl.: `…/security/configs/AvatarConfig#storage()`; consumo: `services/UserAvatarService` |
|
|
200
|
+
| `seedgrid.security.avatar.user-prefix` | String | caminho | `avatars/users` | Não | Prefixo dos avatares de usuário (+ `publicId`) | `UserAvatarService#buildUserPrefix` | — | Runtime | Decl.: `AvatarConfig#userPrefix()` |
|
|
201
|
+
| `seedgrid.security.avatar.default-prefix` | String | caminho | `avatars/defaults` | Não | Prefixo dos avatares padrão | `UserAvatarService#buildDefaultPrefix` | — | Runtime | Decl.: `AvatarConfig#defaultPrefix()` |
|
|
202
|
+
| `seedgrid.security.avatar.public-read` | boolean | `true`/`false` | `false` | Não | `StorageOptions.publicRead` | Upload | — | Runtime | Decl.: `AvatarConfig#publicRead()` |
|
|
203
|
+
| `seedgrid.security.avatar.filesystem.base-path` | String | diretório | `/var/seedgrid/files` | Não | Raiz do storage filesystem | `storage=filesystem` | — | Runtime | Decl.: `AvatarConfig.FilesystemConfig#basePath()`; consumo: `UserAvatarService#buildStorageConfig` |
|
|
204
|
+
| `seedgrid.security.avatar.s3.bucket` | Optional\<String\> | texto | vazio | Condicional (`storage=s3`) | — | `storage=s3` | — | Runtime | Decl.: `AvatarConfig.S3Config#bucket()`; consumo: `buildStorageConfig` |
|
|
205
|
+
| `seedgrid.security.avatar.s3.region` | Optional\<String\> | região AWS | vazio | Condicional | — | `storage=s3` | — | Runtime | Decl.: `S3Config#region()` |
|
|
206
|
+
| `seedgrid.security.avatar.s3.access-key` 🔒 | Optional\<String\> | texto | vazio | Condicional | — | `storage=s3` | — | Runtime | Decl.: `S3Config#accessKey()` |
|
|
207
|
+
| `seedgrid.security.avatar.s3.secret-key` 🔒 | Optional\<String\> | texto | vazio | Condicional | — | `storage=s3` | — | Runtime | Decl.: `S3Config#secretKey()` |
|
|
208
|
+
| `seedgrid.security.avatar.s3.endpoint` | Optional\<String\> | URL | vazio | Não | Endpoint customizado | `storage=s3` | — | Runtime | Decl.: `S3Config#endpoint()` |
|
|
209
|
+
| `seedgrid.security.avatar.minio.bucket` | Optional\<String\> | texto | vazio | Condicional (`storage=minio`) | — | `storage=minio` | — | Runtime | Decl.: `AvatarConfig.MinioConfig#bucket()` |
|
|
210
|
+
| `seedgrid.security.avatar.minio.region` | Optional\<String\> | texto | `us-east-1` (mp-config) | Não | — | `storage=minio` | — | Runtime | Decl.: `MinioConfig#region()` |
|
|
211
|
+
| `seedgrid.security.avatar.minio.access-key` 🔒 | Optional\<String\> | texto | vazio | Condicional | — | `storage=minio` | — | Runtime | Decl.: `MinioConfig#accessKey()` |
|
|
212
|
+
| `seedgrid.security.avatar.minio.secret-key` 🔒 | Optional\<String\> | texto | vazio | Condicional | — | `storage=minio` | — | Runtime | Decl.: `MinioConfig#secretKey()` |
|
|
213
|
+
| `seedgrid.security.avatar.minio.endpoint` | Optional\<String\> | URL | vazio | Condicional | — | `storage=minio` | — | Runtime | Decl.: `MinioConfig#endpoint()` |
|
|
214
|
+
| `seedgrid.security.avatar.azure-blob.connection-string` 🔒 | Optional\<String\> | connection string Azure | vazio | Condicional (`storage=azure-blob`) | — | `storage=azure-blob` | Alternativa a `account-name`+`account-key` (*Inferência*) | Runtime | Decl.: `AvatarConfig.AzureBlobConfig#connectionString()` |
|
|
215
|
+
| `seedgrid.security.avatar.azure-blob.container` | Optional\<String\> | texto | vazio | Condicional | — | `storage=azure-blob` | — | Runtime | Decl.: `AzureBlobConfig#container()` |
|
|
216
|
+
| `seedgrid.security.avatar.azure-blob.account-name` | Optional\<String\> | texto | vazio | Condicional | — | `storage=azure-blob` | — | Runtime | Decl.: `AzureBlobConfig#accountName()` |
|
|
217
|
+
| `seedgrid.security.avatar.azure-blob.account-key` 🔒 | Optional\<String\> | texto | vazio | Condicional | — | `storage=azure-blob` | — | Runtime | Decl.: `AzureBlobConfig#accountKey()` |
|
|
218
|
+
| `seedgrid.security.avatar.google-drive.root-folder-id` | Optional\<String\> | id de pasta | vazio | Condicional (`storage=google-drive`) | — | `storage=google-drive` | — | Runtime | Decl.: `AvatarConfig.GoogleDriveConfig#rootFolderId()` |
|
|
219
|
+
| `seedgrid.security.avatar.google-drive.credentials-file` 🔒 | Optional\<String\> | caminho | vazio | Condicional | — | `storage=google-drive` | Alternativa a `credentials-json` (*Inferência*) | Runtime | Decl.: `GoogleDriveConfig#credentialsFile()` |
|
|
220
|
+
| `seedgrid.security.avatar.google-drive.credentials-json` 🔒 | Optional\<String\> | JSON | vazio | Condicional | — | `storage=google-drive` | — | Runtime | Decl.: `GoogleDriveConfig#credentialsJson()` |
|
|
221
|
+
| `seedgrid.security.avatar.onedrive.client-id` | Optional\<String\> | texto | vazio | Condicional (`storage=onedrive`) | — | `storage=onedrive` | — | Runtime | Decl.: `AvatarConfig.OnedriveConfig#clientId()` |
|
|
222
|
+
| `seedgrid.security.avatar.onedrive.client-secret` 🔒 | Optional\<String\> | texto | vazio | Condicional | — | `storage=onedrive` | — | Runtime | Decl.: `OnedriveConfig#clientSecret()` |
|
|
223
|
+
| `seedgrid.security.avatar.onedrive.tenant-id` | Optional\<String\> | texto | vazio | Condicional | — | `storage=onedrive` | — | Runtime | Decl.: `OnedriveConfig#tenantId()` |
|
|
224
|
+
| `seedgrid.security.avatar.onedrive.root-folder-path` | String | caminho | `/seedgrid/files` | Não | — | `storage=onedrive` | — | Runtime | Decl.: `OnedriveConfig#rootFolderPath()` |
|
|
225
|
+
| `seedgrid.security.avatar.gcs.bucket` | Optional\<String\> | texto | vazio | Condicional (`storage=gcs`) | — | `storage=gcs` | — | Runtime | Decl.: `AvatarConfig.GcsConfig#bucket()` |
|
|
226
|
+
| `seedgrid.security.avatar.gcs.project-id` | Optional\<String\> | texto | vazio | Condicional | — | `storage=gcs` | — | Runtime | Decl.: `GcsConfig#projectId()` |
|
|
227
|
+
| `seedgrid.security.avatar.gcs.credentials-file` 🔒 | Optional\<String\> | caminho | vazio | Condicional | — | `storage=gcs` | — | Runtime | Decl.: `GcsConfig#credentialsFile()` |
|
|
228
|
+
| `seedgrid.security.avatar.gcs.credentials-json` 🔒 | Optional\<String\> | JSON | vazio | Condicional | — | `storage=gcs` | — | Runtime | Decl.: `GcsConfig#credentialsJson()` |
|
|
229
|
+
|
|
230
|
+
Todas as chaves de avatar têm no mp-config a variável `SEEDGRID_SECURITY_AVATAR_<GRUPO>_<CAMPO>` (ex.: `SEEDGRID_SECURITY_AVATAR_S3_SECRET_KEY`), igual à regra padrão.
|
|
231
|
+
|
|
232
|
+
### 2.11 Usuário, RBAC e gestão pela conta
|
|
233
|
+
|
|
234
|
+
| Propriedade | Tipo | Valores aceitos | Padrão | Obrigatória | Comportamento | Uso | Relações | Fase | Origem |
|
|
235
|
+
|---|---|---|---|---|---|---|---|---|---|
|
|
236
|
+
| `seedgrid.security.user.additional-attributes.max-size-bytes` | int | > 0 | `16384` | Não | Tamanho máximo do JSON final (bytes UTF-8) após merge; excedeu → HTTP 400 (`InvalidUserAdditionalAttributesException`) | `POST /users`, `PATCH /users/{publicId}`, `/app/security/users` | env no mp-config: `SEEDGRID_SECURITY_USER_ATTRIBUTES_MAX_SIZE_BYTES` (difere da regra padrão `SEEDGRID_SECURITY_USER_ADDITIONAL_ATTRIBUTES_MAX_SIZE_BYTES`; ambas funcionam — *Inferência* para a padrão) | Runtime | Decl.: `…/security/configs/UserAttributesConfig#maxSizeBytes()`; consumo: `utils/JsonAttributeLimits#check`, `services/UserService` |
|
|
237
|
+
| `seedgrid.security.user.additional-attributes.max-depth` | int | > 0 (raiz = 1) | `5` | Não | Profundidade máxima de aninhamento | idem | env mp-config: `SEEDGRID_SECURITY_USER_ATTRIBUTES_MAX_DEPTH` | Runtime | Decl.: `UserAttributesConfig#maxDepth()`; consumo: `JsonAttributeLimits` |
|
|
238
|
+
| `seedgrid.security.user.additional-attributes.max-keys` | int | > 0 | `100` | Não | Total de chaves em todos os níveis (inclusive dentro de arrays) | idem | env mp-config: `SEEDGRID_SECURITY_USER_ATTRIBUTES_MAX_KEYS` | Runtime | Decl.: `UserAttributesConfig#maxKeys()`; consumo: `JsonAttributeLimits` |
|
|
239
|
+
| `seedgrid.security.rbac.cache-ttl` | Duration | ISO-8601 | `PT5M` | Não | TTL do cache roles→permissões efetivas (chave `security:rbac:perm:` + versão RBAC + nonce de boot + audience + empresa) no `SeedGridCacheProvider` | `RbacSecurityIdentityAugmentor` → `PermissionResolveService#resolve` | Backend de cache vem da lib cache ([[SeedGrid/Extensions/cache/Configuracao\|Configuração do cache]]) | Runtime | Decl.: `…/security/services/PermissionResolveService.RbacConfig#cacheTtl()`; consumo: `PermissionResolveService#resolve` |
|
|
240
|
+
| `seedgrid.security.account.assignable-permission-audiences` | Optional\<List\<String\>\> | lista separada por vírgula (o host define; login-tenancy usa `client`) | — (vazio = só permissões sem audience) | Não | Audiences de permissão que o admin de uma conta pode atribuir aos perfis da conta em `/me/security/roles`; permissão com outra audience → `PermissionNotAssignableException` | `RoleService#resolveAccountAssignablePermissions` | Coluna `permissions.audience` (V223/V234) | Runtime | Decl.: `…/security/configs/AccountManagementConfig#assignablePermissionAudiences()`; consumo: `services/RoleService#accountAudiences` (via `Instance<…>`) |
|
|
241
|
+
|
|
242
|
+
### 2.12 Outras chaves lidas pelo security (`@ConfigProperty`)
|
|
243
|
+
|
|
244
|
+
| Propriedade | Tipo | Valores aceitos | Padrão | Obrigatória | Comportamento | Uso | Relações | Fase | Origem |
|
|
245
|
+
|---|---|---|---|---|---|---|---|---|---|
|
|
246
|
+
| `seedgrid.show-dev-message` | boolean | `true`/`false` | `false` | Não | Inclui mensagem de desenvolvimento nas respostas RFC 7807 das exceções do security | `SecurityApiExceptionExtension` | Chave **compartilhada**: também lida por `seedgrid-quarkus-lib-commons` (`ApiExceptionHandler`), billing e login-tenancy | Runtime | Decl./consumo: `…/security/exceptions/SecurityApiExceptionExtension#showDevMessage` |
|
|
247
|
+
| `seedgrid.app.email-alert.window` | Duration | ISO-8601 | `PT15M` | Não | Anti-flood: só a 1ª falha de envio de e-mail em cada janela publica o evento `platform.email-delivery-failed` no notification (com o total acumulado) | `EmailDeliveryAlertService#emailDeliveryFailed` (chamado pelo `DefaultEmailService`) | Requer `NotificationPublisher` (notification-api) | Runtime | Decl./consumo: `…/security/services/EmailDeliveryAlertService#window` |
|
|
248
|
+
|
|
249
|
+
### 2.13 Rate-limit dos endpoints (`seedgrid.ratelimit.<configKey>.*`)
|
|
250
|
+
|
|
251
|
+
Os limites são declarados no security com `@SeedGridRateLimit(configKey=…)` (lib **resilience**). O `RateLimitService` da resilience lê, em runtime, `seedgrid.ratelimit.<configKey>.{enabled,permits,window,min-spacing,burst-capacity,algorithm}` (`java/seedgrid-quarkus-ext-resilience/runtime/src/main/java/br/com/seedgrid/resilience/core/runtime/ratelimiter/services/RateLimitService.java`). Sem a propriedade vale o valor da anotação; `enabled` default `true`. Detalhes de `algorithm`/`burst-capacity`/`min-spacing`: [[SeedGrid/Extensions/resilience/Configuracao|Configuração do resilience]]. Identidade padrão: IP do cliente.
|
|
252
|
+
|
|
253
|
+
| Propriedade | Tipo | Valores aceitos | Padrão | Obrigatória | Comportamento | Uso | Relações | Fase | Origem |
|
|
254
|
+
|---|---|---|---|---|---|---|---|---|---|
|
|
255
|
+
| `seedgrid.ratelimit.login.{enabled,permits,window}` | boolean / long / Duration | — | `true` / `100` / `PT1M` (anotação) | Não | Limite por IP | `POST /public/auth/login` | — | Runtime | `…/security/controllers/AuthController` (anotação); leitura: resilience `RateLimitService` |
|
|
256
|
+
| `seedgrid.ratelimit.auth-refresh.{enabled,permits,window}` | idem | — | `true` / `30` / `PT1M` | Não | idem | `POST /public/auth/refresh` | — | Runtime | `AuthController` |
|
|
257
|
+
| `seedgrid.ratelimit.auth-confirm-email.{enabled,permits,window}` | idem | — | `true` / `10` / `PT1M` | Não | idem | `GET /public/auth/confirm-email` | — | Runtime | `AuthController` |
|
|
258
|
+
| `seedgrid.ratelimit.forgot-password.{enabled,permits,window}` | idem | — | `true` / `5` / `PT1H` | Não | idem | `POST /public/auth/forgot-password` | — | Runtime | `AuthController` |
|
|
259
|
+
| `seedgrid.ratelimit.auth-reset-password.{enabled,permits,window}` | idem | — | `true` / `10` / `PT1M` | Não | idem | `GET /public/auth/reset-password` | — | Runtime | `AuthController` |
|
|
260
|
+
| `seedgrid.ratelimit.public-companies.{enabled,permits,window}` | idem | — | `true` / `30` / `PT1M` | Não | idem | `GET /public/companies` | — | Runtime | `controllers/CompanyPublicController` |
|
|
261
|
+
| `seedgrid.ratelimit.self-enter-request.{enabled,permits,window}` | idem | — | `true` / `5` / `PT1H` | Não | idem | `POST /public/self-enter/requests` | — | Runtime | `controllers/SelfEnterPublicController` |
|
|
262
|
+
| `seedgrid.ratelimit.self-enter-confirm.{enabled,permits,window}` | idem | — | `true` / `10` / `PT1M` | Não | idem | `POST /public/self-enter/requests/{id}/confirm-email` | — | Runtime | `SelfEnterPublicController` |
|
|
263
|
+
| `seedgrid.ratelimit.self-enter-resend.{enabled,permits,window}` | idem | — | `true` / `3` / `PT1H` | Não | idem | `POST /public/self-enter/requests/{id}/resend-email` | — | Runtime | `SelfEnterPublicController` |
|
|
264
|
+
| `seedgrid.ratelimit.self-enter-invitation.{enabled,permits,window}` | idem | — | `true` / `10` / `PT1M` | Não | idem | `GET /public/self-enter/invitations/{token}` | — | Runtime | `SelfEnterPublicController` |
|
|
265
|
+
| `seedgrid.ratelimit.self-enter-complete.{enabled,permits,window}` | idem | — | `true` / `5` / `PT1M` | Não | idem | `POST /public/self-enter/invitations/{token}/complete` | — | Runtime | `SelfEnterPublicController` |
|
|
266
|
+
| `seedgrid.ratelimit.2fa-verify.{enabled,permits,window}` | idem | — | `true` / `5` / `PT15M` | Não | idem | `POST /public/2f/verify` | Complementa `2f.verify.max-attempts` | Runtime | `controllers/TwoFactorPublicController` |
|
|
267
|
+
| `seedgrid.ratelimit.2fa-resend.{enabled,permits,window}` | idem | — | `true` / `3` / `PT1H` | Não | idem | `POST /public/2f/resend` | — | Runtime | `TwoFactorPublicController` |
|
|
268
|
+
| `seedgrid.ratelimit.user-activation-resend.{enabled,permits,window}` | idem | — | `true` / `3` / `PT1H` | Não | idem | `POST /me/security/users/{id}/resend-activation` | — | Runtime | `controllers/AccountUserController` |
|
|
269
|
+
|
|
270
|
+
Para cada `configKey` acima também existem `.min-spacing` (Duration), `.burst-capacity` (long) e `.algorithm` (String) — não usados pelas anotações do security (valores da anotação: algoritmo `FIXED_WINDOW`, burst 0, spacing 0).
|
|
271
|
+
|
|
272
|
+
Env var: chaves que começam com dígito após o ponto (`2fa-verify`) viram `SEEDGRID_RATELIMIT_2FA_VERIFY_ENABLED` pela regra padrão (*Inferência*, sem ambiguidade aparente).
|
|
273
|
+
|
|
274
|
+
---
|
|
275
|
+
|
|
276
|
+
## 3. Propriedades de frameworks/bibliotecas configuradas pela extension
|
|
277
|
+
|
|
278
|
+
Definidas no `mp-config` (ordinal 100 — o host pode sobrescrever):
|
|
279
|
+
|
|
280
|
+
| Propriedade | Valor no mp-config | Para quê |
|
|
281
|
+
|---|---|---|
|
|
282
|
+
| `quarkus.hibernate-orm.mapping.format.global` | `ignore` | JSONB (`additionalAttributes`) usa o mapper JSON do Hibernate diretamente |
|
|
283
|
+
| `quarkus.http.auth.proactive` | `true` | Autenticação proativa (o comentário fala em "apenas rota protegida", mas o valor é `true` — ver §9) |
|
|
284
|
+
| `quarkus.smallrye-openapi.security-scheme` | `jwt` | Declara o esquema bearer |
|
|
285
|
+
| `quarkus.smallrye-openapi.security-scheme-name` | `bearerAuth` | Nome do esquema |
|
|
286
|
+
| `quarkus.smallrye-openapi.auto-add-security` | `false` | Requirements aplicados seletivamente pelo `JwtSecurityOpenApiFilter` (só não-públicos) |
|
|
287
|
+
| `quarkus.swagger-ui.path` | `/swagger-ui` | — |
|
|
288
|
+
| `quarkus.swagger-ui.always-include` | `true` | Swagger UI também em produção |
|
|
289
|
+
| `quarkus.mailer."security".from` / `.host` / `.port` / `.start-tls` / `.username` 🔒 / `.password` 🔒 / `.auth-methods` | `${seedgrid.security.mailer.<mesmo-campo>}` | Bridge para o mailer nomeado `security` |
|
|
290
|
+
| `mp.jwt.verify.publickey.location` | `${seedgrid.security.jwt.public-key-location}` | `SecurityIdentity` via quarkus-smallrye-jwt |
|
|
291
|
+
| `mp.jwt.verify.issuer` | `${seedgrid.security.jwt.issuer}` | idem |
|
|
292
|
+
|
|
293
|
+
Chaves de **outra extension** definidas no mp-config do security:
|
|
294
|
+
|
|
295
|
+
| Propriedade | Valor | Observação |
|
|
296
|
+
|---|---|---|
|
|
297
|
+
| `seedgrid.whatsapp.api` | `${SEEDGRID_WHATSAPP_API:evolution}` | Seleciona o provedor WhatsApp (`@LookupIfProperty` na extension whatsapp). O `microprofile-config.properties` do `seedgrid-whatsapp-core` também define essa chave (`${SEEDGRID_WHATSAPP_API:default}`) com o mesmo ordinal 100 — qual vence não é determinístico; **defina explicitamente** no host. As demais chaves do provedor são `seedgrid.whatsapp.*` — ver [[SeedGrid/Extensions/whatsapp/Configuracao\|Configuração do whatsapp]]. |
|
|
298
|
+
|
|
299
|
+
Recomendadas/exigidas para o host (README e `application.properties` de teste):
|
|
300
|
+
|
|
301
|
+
| Propriedade | Valor | Motivo |
|
|
302
|
+
|---|---|---|
|
|
303
|
+
| `quarkus.flyway.migrate-at-start` | `true` | Aplicar migrations V200–V235 |
|
|
304
|
+
| `quarkus.flyway.locations` | `classpath:db/migration/security` (+ `classpath:db/migration/audit` se usar audit) | Local das migrations |
|
|
305
|
+
| `quarkus.hibernate-orm.physical-naming-strategy` | `org.hibernate.boot.model.naming.CamelCaseToUnderscoresNamingStrategy` | Nomes de coluna das entidades |
|
|
306
|
+
| `quarkus.datasource.*` | PostgreSQL | Migrations e entidades são PostgreSQL (JSONB) |
|
|
307
|
+
| `seedgrid.privacy.encryption.enabled`, `seedgrid.privacy.crypto.key` 🔒, `seedgrid.privacy.search.key` 🔒 | opcional | Cifra PII de `User`/`Company`/`EntryRequest` at-rest (lib privacy — ver [[SeedGrid/Extensions/privacy/Configuracao\|Configuração do privacy]]) |
|
|
308
|
+
|
|
309
|
+
---
|
|
310
|
+
|
|
311
|
+
## 4. Propriedades usadas só em testes
|
|
312
|
+
|
|
313
|
+
`java/seedgrid-quarkus-ext-security/runtime/src/test/resources/application.properties` e `QuarkusTestProfile`s em `runtime/src/test/java/br/com/seedgrid/security/`:
|
|
314
|
+
|
|
315
|
+
| Propriedade | Onde | Valor/uso |
|
|
316
|
+
|---|---|---|
|
|
317
|
+
| `quarkus.datasource.db-kind`, `quarkus.datasource.devservices.enabled`, `quarkus.hibernate-orm.database.generation`, `quarkus.hibernate-orm.sql-load-script`, `quarkus.flyway.clean-at-start`, `quarkus.index-dependency.seedgrid-filemanagement.*`, `quarkus.arc.exclude-types`, `quarkus.http.test-port`, `quarkus.http.root-path=/api`, `quarkus.log.*` | `application.properties` (teste) | Infra de teste (Postgres via `PostgreSqlTestResourceLifecycleManager`, que injeta `quarkus.datasource.username/password/jdbc.url` e `seedgrid.audit.jpa.*`) |
|
|
318
|
+
| `smallrye.jwt.sign.key.location`, `smallrye.jwt.new-token.issuer`, `smallrye.jwt.new-token.lifespan`, `mp.jwt.verify.*` | idem | Chaves de teste `test-privatekey.pem`/`test-publickey.pem` |
|
|
319
|
+
| `quarkus.mailer.mock`, `quarkus.mailer."security".mock` | idem | Mailer mock |
|
|
320
|
+
| `seedgrid.audit.persistence.strategy=JPA`, `seedgrid.audit.jpa.db-kind` | idem | Audit |
|
|
321
|
+
| `seedgrid.security.refresh-token.reuse-grace-window=PT0S` | idem | Janela desligada; religada em `RefreshTokenGraceWindowProfile` |
|
|
322
|
+
| `seedgrid.ratelimit.<todas as 14 chaves>.enabled=false` | idem | Evita flakiness da suite |
|
|
323
|
+
| `seedgrid.security.account.assignable-permission-audiences=client` | idem | Convenção do login-tenancy |
|
|
324
|
+
| `seedgrid.security.self-enter.*`, `seedgrid.security.2f.*`, `seedgrid.security.bootstrap.enabled`, `seedgrid.security.first-admin-user.*`, `seedgrid.security.default-company.*` | Profiles `SelfEnter*Profile`, `BootstrapDisabledProfile`, `FirstAdminBootstrapProfile` | Variações por cenário |
|
|
325
|
+
| `seedgrid.privacy.encryption.enabled`, `seedgrid.privacy.crypto.key`, `seedgrid.privacy.search.key` | `EncryptedFieldsSecurityTest` | Teste de PII cifrada |
|
|
326
|
+
|
|
327
|
+
O exemplo `java/examples/seedgrid-security-example` (repo próprio, commit `86cfc37`) usa nomes de env diferentes (`SECURITY_JWT_ISSUER`, `SECURITY_MAILER_FROM`…) via expressões no seu `application.properties` — são escolhas do exemplo, não aliases da extension.
|
|
328
|
+
|
|
329
|
+
---
|
|
330
|
+
|
|
331
|
+
## 5. Aliases e defaults efetivos
|
|
332
|
+
|
|
333
|
+
Não há aliases nem nomes alternativos lidos pelo código. Atenção ao default **efetivo**, que vem do mp-config e difere do `@WithDefault` em:
|
|
334
|
+
|
|
335
|
+
- `seedgrid.security.2f.enabled`: efetivo `true` (`@WithDefault` `false`).
|
|
336
|
+
- `seedgrid.security.self-enter.default-role`: **sem valor padrão**; obrigatória com `self-enter.enabled=true`.
|
|
337
|
+
- `seedgrid.security.password.*`: valores permissivos do mp-config (`min-size=1`, demais `false`/`0`); a interface não tem `@WithDefault`.
|
|
338
|
+
|
|
339
|
+
---
|
|
340
|
+
|
|
341
|
+
## 6. Configuração mínima (`application.properties` do host)
|
|
342
|
+
|
|
343
|
+
```properties
|
|
344
|
+
# Obrigatória sem default em lugar nenhum
|
|
345
|
+
seedgrid.security.encryption.key=<SEGREDO:security-encryption-key-base64-32-bytes>
|
|
346
|
+
|
|
347
|
+
# Empresa-plataforma (o mp-config aponta para env SEM default)
|
|
348
|
+
seedgrid.security.default-company.cnpj=<CNPJ-da-plataforma>
|
|
349
|
+
seedgrid.security.default-company.corporate-name=<razao-social>
|
|
350
|
+
seedgrid.security.default-company.trade-name=<nome-fantasia>
|
|
351
|
+
|
|
352
|
+
# Chaves RSA (ou deixe os arquivos keys/private.pem e keys/public.pem no classpath/diretório de trabalho)
|
|
353
|
+
seedgrid.security.jwt.private-key-location=<caminho>/private.pem
|
|
354
|
+
seedgrid.security.jwt.public-key-location=<caminho>/public.pem
|
|
355
|
+
|
|
356
|
+
# Valores do mp-config que NÃO servem para produção
|
|
357
|
+
seedgrid.security.mailer.from=noreply@<seu-dominio>
|
|
358
|
+
seedgrid.security.frontend.base-url=https://<app.seu-dominio>
|
|
359
|
+
seedgrid.security.password.min-size=8
|
|
360
|
+
|
|
361
|
+
# Infra
|
|
362
|
+
quarkus.flyway.migrate-at-start=true
|
|
363
|
+
quarkus.flyway.locations=classpath:db/migration/security
|
|
364
|
+
quarkus.hibernate-orm.physical-naming-strategy=org.hibernate.boot.model.naming.CamelCaseToUnderscoresNamingStrategy
|
|
365
|
+
```
|
|
366
|
+
|
|
367
|
+
## 7. Configuração completa comentada
|
|
368
|
+
|
|
369
|
+
Valores abaixo são **escolhas de exemplo válidas**; os padrões reais estão nas tabelas.
|
|
370
|
+
|
|
371
|
+
```properties
|
|
372
|
+
# ---------- JWT ----------
|
|
373
|
+
seedgrid.security.jwt.issuer=https://<seu-dominio>
|
|
374
|
+
seedgrid.security.jwt.kid=<id-da-chave>
|
|
375
|
+
seedgrid.security.jwt.ttl=PT8H
|
|
376
|
+
# Opção A: arquivos PEM (filesystem primeiro, depois classpath)
|
|
377
|
+
seedgrid.security.jwt.private-key-location=keys/private.pem
|
|
378
|
+
seedgrid.security.jwt.public-key-location=keys/public.pem
|
|
379
|
+
# Opção B: base64 (precedência sobre location). Defina também MP_JWT_VERIFY_PUBLICKEY.
|
|
380
|
+
#seedgrid.security.jwt.private-key-base64=<SEGREDO:jwt-private-key-pkcs8-base64>
|
|
381
|
+
#seedgrid.security.jwt.public-key-base64=<jwt-public-key-x509-base64>
|
|
382
|
+
|
|
383
|
+
# ---------- Refresh token ----------
|
|
384
|
+
seedgrid.security.refresh-token.ttl=P30D
|
|
385
|
+
seedgrid.security.refresh-token.reuse-grace-window=PT30S
|
|
386
|
+
|
|
387
|
+
# ---------- Criptografia de segredos internos (TOTP, senha de bootstrap) ----------
|
|
388
|
+
seedgrid.security.encryption.key=<SEGREDO:security-encryption-key-base64-32-bytes>
|
|
389
|
+
|
|
390
|
+
# ---------- Política de senha ----------
|
|
391
|
+
seedgrid.security.password.min-size=8
|
|
392
|
+
seedgrid.security.password.max-history=5
|
|
393
|
+
seedgrid.security.password.upper-case-required=true
|
|
394
|
+
seedgrid.security.password.lower-case-required=true
|
|
395
|
+
seedgrid.security.password.special-character-required=true
|
|
396
|
+
seedgrid.security.password.prohibits-repeated-characters-in-sequence=false
|
|
397
|
+
seedgrid.security.password.expiration-days=0
|
|
398
|
+
|
|
399
|
+
# ---------- 2FA ----------
|
|
400
|
+
seedgrid.security.2f.enabled=true
|
|
401
|
+
seedgrid.security.2f.allowed-methods=EMAIL,TOTP,WHATSAPP
|
|
402
|
+
seedgrid.security.2f.totp.issuer=<NomeDoApp>
|
|
403
|
+
seedgrid.security.2f.totp.digits=6
|
|
404
|
+
seedgrid.security.2f.totp.period=30
|
|
405
|
+
seedgrid.security.2f.totp.window=1
|
|
406
|
+
seedgrid.security.2f.otp-qrcode.branding.enabled=false
|
|
407
|
+
#seedgrid.security.2f.otp-qrcode.logo=classpath:/images/logo.png
|
|
408
|
+
seedgrid.security.2f.otp-qrcode.size=256
|
|
409
|
+
seedgrid.security.2f.verify.max-attempts=5
|
|
410
|
+
seedgrid.security.2f.session.ttl=PT5M
|
|
411
|
+
seedgrid.security.2f.email.code-ttl=PT5M
|
|
412
|
+
seedgrid.security.2f.backup-codes.count=10
|
|
413
|
+
seedgrid.security.2f.backup-codes.length=6
|
|
414
|
+
seedgrid.security.2f.whatsapp.channel-id=<id-do-canal-whatsapp>
|
|
415
|
+
seedgrid.security.2f.whatsapp.code-ttl=PT5M
|
|
416
|
+
|
|
417
|
+
# ---------- Self-enter ----------
|
|
418
|
+
seedgrid.security.self-enter.enabled=true
|
|
419
|
+
seedgrid.security.self-enter.public-enabled=true
|
|
420
|
+
seedgrid.security.self-enter.invite-enabled=true
|
|
421
|
+
seedgrid.security.self-enter.invite-needs-approval=true
|
|
422
|
+
seedgrid.security.self-enter.request-ttl=PT48H
|
|
423
|
+
seedgrid.security.self-enter.invite-ttl=PT168H
|
|
424
|
+
seedgrid.security.self-enter.email-token-ttl=PT30M
|
|
425
|
+
seedgrid.security.self-enter.default-role=<NOME-DA-ROLE-GLOBAL> # obrigatória se self-enter.enabled=true
|
|
426
|
+
seedgrid.security.self-enter.cleanup.enabled=true
|
|
427
|
+
seedgrid.security.self-enter.cleanup.cron=0 */10 * * * ?
|
|
428
|
+
seedgrid.security.self-enter.cleanup.purge-after=PT168H
|
|
429
|
+
seedgrid.security.self-enter.email.confirm-subject=Confirme seu e-mail
|
|
430
|
+
seedgrid.security.self-enter.email.invite-subject=Voce recebeu um convite para cadastro
|
|
431
|
+
|
|
432
|
+
# ---------- E-mail (mailer nomeado "security") ----------
|
|
433
|
+
seedgrid.security.mailer.from=noreply@<seu-dominio>
|
|
434
|
+
seedgrid.security.mailer.host=<smtp-host>
|
|
435
|
+
seedgrid.security.mailer.port=587
|
|
436
|
+
seedgrid.security.mailer.start-tls=REQUIRED
|
|
437
|
+
seedgrid.security.mailer.username=<usuario-smtp>
|
|
438
|
+
seedgrid.security.mailer.password=<SEGREDO:smtp-password>
|
|
439
|
+
seedgrid.security.mailer.auth-methods=PLAIN LOGIN
|
|
440
|
+
seedgrid.app.email-alert.window=PT15M
|
|
441
|
+
|
|
442
|
+
# ---------- Frontend (links dos e-mails) ----------
|
|
443
|
+
seedgrid.security.frontend.base-url=https://<app.seu-dominio>
|
|
444
|
+
seedgrid.security.frontend.login-path=/login
|
|
445
|
+
seedgrid.security.frontend.password-reset-path=/auth/forgot-password/confirm
|
|
446
|
+
seedgrid.security.frontend.email-confirmation-path=/auth/confirm-email
|
|
447
|
+
seedgrid.security.frontend.welcome-path=/auth/welcome
|
|
448
|
+
seedgrid.security.frontend.self-enter-path=/auth/self-enter/invitation
|
|
449
|
+
|
|
450
|
+
# ---------- Bootstrap ----------
|
|
451
|
+
seedgrid.security.bootstrap.enabled=true
|
|
452
|
+
seedgrid.security.default-company.cnpj=<CNPJ>
|
|
453
|
+
seedgrid.security.default-company.corporate-name=<razao-social>
|
|
454
|
+
seedgrid.security.default-company.trade-name=<nome-fantasia>
|
|
455
|
+
#seedgrid.security.default-company.addr-street=... (addr-number, addr-complement, addr-postal-code, addr-city, addr-state, addr-district, addr-phone)
|
|
456
|
+
#seedgrid.security.default-company.rep-first-name=... (rep-last-name, rep-cpf, rep-birth-date, rep-phone, rep-whatsapp, rep-email)
|
|
457
|
+
seedgrid.security.first-admin-user.email=<admin@seu-dominio>
|
|
458
|
+
seedgrid.security.first-admin-user.name=<Nome do Admin>
|
|
459
|
+
#seedgrid.security.first-admin-user.whatsapp=<+55...>
|
|
460
|
+
#seedgrid.security.first-admin-user.initial-password=<SEGREDO:first-admin-initial-password>
|
|
461
|
+
|
|
462
|
+
# ---------- Avatar ----------
|
|
463
|
+
seedgrid.security.avatar.storage=filesystem
|
|
464
|
+
seedgrid.security.avatar.user-prefix=avatars/users
|
|
465
|
+
seedgrid.security.avatar.default-prefix=avatars/defaults
|
|
466
|
+
seedgrid.security.avatar.public-read=false
|
|
467
|
+
seedgrid.security.avatar.filesystem.base-path=/var/seedgrid/files
|
|
468
|
+
# s3: bucket, region, access-key, secret-key, endpoint | minio: idem | azure-blob: connection-string, container,
|
|
469
|
+
# account-name, account-key | google-drive: root-folder-id, credentials-file, credentials-json |
|
|
470
|
+
# onedrive: client-id, client-secret, tenant-id, root-folder-path | gcs: bucket, project-id, credentials-file, credentials-json
|
|
471
|
+
|
|
472
|
+
# ---------- Usuário / RBAC / conta ----------
|
|
473
|
+
seedgrid.security.user.additional-attributes.max-size-bytes=16384
|
|
474
|
+
seedgrid.security.user.additional-attributes.max-depth=5
|
|
475
|
+
seedgrid.security.user.additional-attributes.max-keys=100
|
|
476
|
+
seedgrid.security.rbac.cache-ttl=PT5M
|
|
477
|
+
#seedgrid.security.account.assignable-permission-audiences=client
|
|
478
|
+
|
|
479
|
+
# ---------- Erros ----------
|
|
480
|
+
seedgrid.show-dev-message=false
|
|
481
|
+
|
|
482
|
+
# ---------- Rate-limit (lib resilience) ----------
|
|
483
|
+
#seedgrid.ratelimit.login.permits=100
|
|
484
|
+
#seedgrid.ratelimit.login.window=PT1M
|
|
485
|
+
#seedgrid.ratelimit.login.enabled=true
|
|
486
|
+
```
|
|
487
|
+
|
|
488
|
+
## 8. Receitas
|
|
489
|
+
|
|
490
|
+
**Produção com banco único (padrão).** Configuração mínima (§6) + SMTP real + política de senha forte + `seedgrid.security.first-admin-user.email` para nascer o 1º admin. Se ligar self-enter, `seedgrid.security.self-enter.default-role` é obrigatória (a aplicação não sobe sem ela): informe o nome exato de uma role **global** existente. Convite sem roles auto-aprovado (`invite-needs-approval=false`) cria o usuário com essa role.
|
|
491
|
+
|
|
492
|
+
**Host database-per-tenant (subdomain-tenancy).** `seedgrid.security.bootstrap.enabled=false` (empresa e admin nascem no provisionamento do tenant). Ainda é preciso definir `default-company.cnpj/corporate-name/trade-name` (mapping obrigatório) — o teste `BootstrapDisabledTest` faz isso.
|
|
493
|
+
|
|
494
|
+
**Desligar 2FA.** `seedgrid.security.2f.enabled=false` (o mp-config liga por padrão).
|
|
495
|
+
|
|
496
|
+
**2FA por WhatsApp.** `seedgrid.security.2f.allowed-methods=EMAIL,TOTP,WHATSAPP`, `seedgrid.security.2f.whatsapp.channel-id=<canal>` e configurar a extension whatsapp (`seedgrid.whatsapp.api=evolution|cloud` + chaves `seedgrid.whatsapp.*`).
|
|
497
|
+
|
|
498
|
+
**Só convites, sem signup público, sem aprovação manual.** `self-enter.enabled=true`, `self-enter.public-enabled=false`, `self-enter.invite-enabled=true`, `self-enter.invite-needs-approval=false` (cenário coberto por `SelfEnterInviteOnlyProfile` + `SelfEnterInviteAutoApproveProfile`).
|
|
499
|
+
|
|
500
|
+
**Chaves RSA por variável de ambiente (containers).** `SEEDGRID_SECURITY_JWT_PRIVATE_KEY_BASE64`, `SEEDGRID_SECURITY_JWT_PUBLIC_KEY_BASE64` **e** `MP_JWT_VERIFY_PUBLICKEY` (o bridge só cobre `location`).
|
|
501
|
+
|
|
502
|
+
**Avatares em MinIO.** `seedgrid.security.avatar.storage=minio` + `minio.bucket`, `minio.endpoint`, `minio.access-key`, `minio.secret-key` (região default `us-east-1`).
|
|
503
|
+
|
|
504
|
+
**Afrouxar/desligar um rate-limit.** `seedgrid.ratelimit.auth-refresh.permits=60` ou `seedgrid.ratelimit.login.enabled=false`.
|
|
505
|
+
|
|
506
|
+
## 9. Dúvidas e lacunas
|
|
507
|
+
|
|
508
|
+
- O e-mail de aprovação do self-enter **não é enviado**: `SelfEnterService#sendApprovalEmail` só registra log. Por isso `TemplateSecurityProvider#entryRequestApproved` e o template `entry-request-approved.html` não têm efeito hoje.
|
|
509
|
+
- Política de senha com defaults permissivos no mp-config (min-size 1) — sobrescreva no host.
|
|
510
|
+
- Validação de obrigatoriedade das chaves de avatar por backend fica na lib filemanagement — não verificada aqui.
|