Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
7c67231
docs: adiciona ADR de segregacao Decrypt/LowCodeRunner em servicos de…
elson-lopes Sep 25, 2026
d118961
feat(decrypt): substitui Process.Start por HttpClient+Polly para o se…
elson-lopes Sep 25, 2026
dec3045
docs(adr): corrige achado tecnico do §1 sobre RijndaelManaged em .NET…
elson-lopes Sep 25, 2026
0874856
Merge pull request #568 from LayoutParser/docs/adr-segregacao-decrypt…
elson-vinicius-lopes Sep 25, 2026
ea62213
chore(ci): harmoniza workflows com o padrao de hardening do layoutpar…
elson-lopes Sep 25, 2026
76ab17e
chore(ci): reativa CodeQL agora que os repos do ecossistema sao publicos
elson-lopes Sep 25, 2026
c628fe7
Merge pull request #571 from LayoutParser/chore/ci-security-hardening…
elson-vinicius-lopes Sep 25, 2026
d8bbd82
docs: atualiza nomes de repositorio para lowercase-com-hifen
elson-lopes Sep 25, 2026
5c46d6c
chore: atualiza referencias de path/repo para os nomes lowercase-com-…
elson-lopes Sep 25, 2026
5a97d8c
docs: remove paragrafos duplicados no README (fieldMappings/sectionMa…
elson-lopes Sep 25, 2026
f887d89
Merge pull request #573 from LayoutParser/chore/rename-repos-lowercase
elson-vinicius-lopes Sep 25, 2026
a90a545
Merge branch 'origin/develop' into docs/remove-duplicated-readme-para…
elson-lopes Sep 25, 2026
b3e37c8
Merge pull request #574 from LayoutParser/docs/remove-duplicated-read…
elson-vinicius-lopes Sep 25, 2026
2096a35
chore(deps): Bump the runtime-minor-patch group with 2 updates
dependabot[bot] Sep 28, 2026
87c589a
Merge pull request #582 from LayoutParser/dependabot/nuget/ai/XslSynt…
elson-vinicius-lopes Sep 28, 2026
47976a4
Merge pull request #569 from LayoutParser/feat/decrypt-http-client-adr
elson-vinicius-lopes Sep 28, 2026
268f9e4
Merge pull request #572 from LayoutParser/chore/codeql-reactivation-p…
elson-vinicius-lopes Sep 28, 2026
c5035ba
feat(migracao-linux): hosting systemd, redes confiaveis de identidade…
elson-lopes Sep 28, 2026
9dac662
fix(ci): remove codeql.yml avancado; default setup do GitHub ja cobre…
elson-lopes Sep 28, 2026
8fb0578
feat(ci): pipelines Linux paralelos e docs das fases 2-4 (#577 #578 #…
elson-lopes Sep 28, 2026
65a9b67
Merge pull request #583 from LayoutParser/fix/codeql-remove-advanced-…
elson-vinicius-lopes Sep 28, 2026
1a86689
Merge pull request #584 from LayoutParser/feat/migracao-linux-fases-575
elson-vinicius-lopes Sep 28, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions .claude/CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,10 @@ transformações (**XSLT/TCL**). É o **hub** de um ecossistema de 4 repositóri

| Repo | Papel |
|------|-------|
| **LayoutParserApi** *(este)* | Orquestra parse, cache, IA, transformação. Source of truth do runtime. |
| **LayoutParserLib** | Criptografia Sysmiddle (DLL referenciada). |
| **LayoutParserDecrypt** | `.exe` de descriptografia (processo externo). |
| **LayoutParserReact** | Front-end (Vite + React). |
| **layoutparser-api** *(este)* | Orquestra parse, cache, IA, transformação. Source of truth do runtime. |
| **layoutparser-lib** | Criptografia Sysmiddle (DLL referenciada). |
| **layoutparser-decrypt** | `.exe` de descriptografia (processo externo). |
| **layoutparser-portal** | Front-end (Vite + React). |

Contexto completo: [`README.md`](../README.md).

Expand Down
45 changes: 44 additions & 1 deletion .claude/rules/security.md
Original file line number Diff line number Diff line change
Expand Up @@ -323,6 +323,49 @@ não ao Dependabot version updates. Nenhuma ação necessária no `dependabot.ym
2. `dependabot.yml` — **não mexer**, já é 100% gratuito e correto.
3. `SecurityCodeScan` + baseline — **não mexer**, é o substituto ativo do CodeQL.

## CodeQL REATIVADO — repos voltaram a público (2026-09-25)

A premissa da remoção acima (repo privado → GHAS pago) **deixou de valer**. Os 3 repos do
ecossistema (`LayoutParserApi`, `LayoutParserDecrypt`, `layoutparser-portal`) estão **públicos**
desde a limpeza de histórico de 2026-08-15 (ver seção "🔴🔴 2026-08-15" acima — a decisão de
manter público foi tomada ali, não revertida). Em repositório **público**, code scanning via
`github/codeql-action` é **gratuito**, sem exigir GHAS/licença. O `layoutparser-portal` já
reativou o CodeQL nesse meio-tempo (`javascript-typescript` + `actions`, `build-mode: none`) e
serviu de template para esta reativação — confirmado sem necessidade de mudança.

**Ações desta sessão:**

1. **`LayoutParserApi`** — recriado `.github/workflows/codeql.yml`. `on:` usa `develop`/`master`
(não `main` — branches reais deste repo, confirmado via `git branch -a`). Matriz:
`csharp` + `actions`. `build-mode: none` (não `autobuild`) — decisão deliberada: o
`LayoutParserApi.csproj` referencia `LayoutParserLib` via `HintPath` relativo a um repo
**irmão** (`..\LayoutParserLib\bin\$(Configuration)\LayoutParserLib.dll`) que não existe no
checkout isolado do workflow (o CodeQL só clona este repo). Um `autobuild` real quebraria
nessa `Reference` ausente. `build-mode: none` para C# é suportado desde CodeQL CLI 2.16 —
faz extração/análise direta do código-fonte sem precisar resolver todas as referências,
cobrindo o mesmo escopo de `security-extended` (SQLi, path traversal etc.) sem depender de
build completo. **Limitação conhecida e não resolvida:** análise fluxo-sensível que dependa
de tipos/símbolos definidos em `LayoutParserLib` (não neste repo) pode ficar mais fraca do
que um build real conseguiria — se isso incomodar no futuro, a alternativa é um step manual
que primeiro reconstrói um stub de `LayoutParserLib.dll` antes do `dotnet build`
(`build-mode: manual`), não implementado aqui.
2. **`LayoutParserDecrypt`** — recriado `.github/workflows/codeql.yml` no repo. `on:` usa só
`master` (sem `develop` — fluxo real deste repo é `feat/** → master` direto, confirmado via
`git branch -a`). Matriz: `csharp` + `actions`. Diferente da API, este projeto é **standalone**
(o próprio `.csproj` documenta em comentário que o código de `LayoutParserLib` foi embutido
como arquivos-fonte locais exatamente para não depender de repo irmão) — mas é um projeto
**clássico não-SDK** (`TargetFrameworkVersion v4.8.1`, `OutputType Exe`), que exige MSBuild
(não `dotnet build`) e por isso o `build.yml` existente já roda em `windows-latest` com
`microsoft/setup-msbuild` + `nuget restore`/`msbuild` explícitos, não `dotnet`.
`build-mode: none` do CodeQL roda em `ubuntu-latest` e não builda nada — não tem esse
problema, mas também não se beneficia da build real já validada no `build.yml`. Optou-se por
manter `build-mode: none` + `ubuntu-latest` (mesmo padrão dos outros dois repos, mais simples
e sem custo de manter um segundo caminho de build MSBuild dentro do CodeQL) — se no futuro
quiser uma análise mais profunda equivalente ao `autobuild`, o caminho seria
`build-mode: manual` em `windows-latest` reaproveitando os mesmos steps de
`setup-msbuild`/`nuget restore`/`msbuild` do `build.yml`.
3. **`layoutparser-portal`** — conferido, sem alteração necessária.

## Regras gerais (todos os agentes)

- **NUNCA** comite segredos, connection strings ou tokens.
Expand All @@ -333,7 +376,7 @@ não ao Dependabot version updates. Nenhuma ação necessária no `dependabot.ym
- **Identidade vem do BFF, não há `[Authorize]` ainda.** A API não autentica ninguém diretamente:
`Services/Security/TrustedIdentityMiddleware.cs` lê os headers `x-iis-user`/`x-iis-roles`
(configuráveis via `Security:TrustedUserHeader`/`Security:TrustedRolesHeader`) injetados pelo BFF
Fastify (`LayoutParserReact/server/`, autenticação Entra OIDC) e popula `ICurrentUser` +
Fastify (`layoutparser-portal/server/`, autenticação Entra OIDC) e popula `ICurrentUser` +
`HttpContext.User`. Só confia nesses headers se a origem da requisição for **loopback**
(`TrustIdentityFromLoopbackOnly`, default `true`, deliberadamente fora do `appsettings.json`) —
isso fecha forja de identidade mesmo com a API respondendo em `0.0.0.0`. Nenhum endpoint tem
Expand Down
83 changes: 83 additions & 0 deletions .github/workflows/ci-dev-linux.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
name: CI Dev Linux (LayoutParserApi)

# Fase 3 da migracao Linux (issue #578, Epic #575). Pipeline PARALELO ao ci-dev.yml (Windows).
# Somente workflow_dispatch: NAO substitui o pipeline Windows - rollback = nao usar este arquivo.
# Runner: label 'linux' + 'dev-local'. Deploy via systemd + EnvironmentFile (sem registro do Windows).
# Arquivos de apoio: deploy/linux/layoutparser-api.service e deploy/linux/secrets.env.example.

on:
workflow_dispatch:

permissions:
contents: read

concurrency:
group: ci-dev-linux-${{ github.ref }}
cancel-in-progress: true

jobs:
build-deploy:
runs-on: [self-hosted, linux, dev-local]
timeout-minutes: 30
env:
DEPLOY_PATH: ${{ vars.DEPLOY_PATH_DEV_LINUX || '/opt/layoutparser-api' }}
API_URL: ${{ vars.API_URL_DEV_LINUX || 'http://localhost:5100' }}
steps:
- uses: actions/checkout@v7
with:
path: layoutparser-api

# BLOQUEIO CONHECIDO (Fase 1, #576): a API referencia LayoutParserLib.dll (net48/HintPath).
# Enquanto a Lib nao for portada/sidecar, este build so passa se a DLL estiver disponivel.
- uses: actions/checkout@v7
with:
repository: LayoutParser/layoutparser-lib
path: layoutparser-lib
token: ${{ secrets.GH_PAT_TOKEN || secrets.GITHUB_TOKEN }}
fetch-depth: 1

- uses: actions/setup-dotnet@v6
with:
dotnet-version: '10.0.x'

- name: Build LayoutParserLib (Debug)
run: dotnet build layoutparser-lib/LayoutParserLib.csproj --configuration Debug

- name: Build e testes
run: |
dotnet restore layoutparser-api/LayoutParserApi.csproj
dotnet build layoutparser-api/LayoutParserApi.csproj -c Release --no-restore
dotnet test layoutparser-api --no-restore -c Release --verbosity minimal

- name: Publish
run: dotnet publish layoutparser-api/LayoutParserApi.csproj -c Release -o "$RUNNER_TEMP/publish"

# Segredos ficam em /etc/layoutparser-api/secrets.env (chmod 600, provisionado uma vez pelo
# operador a partir de deploy/linux/secrets.env.example) - o workflow NUNCA escreve segredo.
- name: Deploy (systemd)
run: |
set -euo pipefail
test -f /etc/layoutparser-api/secrets.env || { echo "secrets.env ausente - ver deploy/linux/secrets.env.example"; exit 1; }
sudo rm -rf "${DEPLOY_PATH}.prev"; [ -d "$DEPLOY_PATH" ] && sudo cp -a "$DEPLOY_PATH" "${DEPLOY_PATH}.prev" || true
sudo mkdir -p "$DEPLOY_PATH"
sudo rsync -a --delete --exclude 'appsettings.Production.json' "$RUNNER_TEMP/publish/" "$DEPLOY_PATH/"
sudo cp layoutparser-api/deploy/linux/layoutparser-api.service /etc/systemd/system/layoutparser-api.service
sudo systemctl daemon-reload
sudo systemctl enable layoutparser-api
sudo systemctl restart layoutparser-api

- name: Smoke test de readiness
run: |
for i in $(seq 1 12); do
code=$(curl -s -o /tmp/ready.json -w '%{http_code}' "$API_URL/health/ready" || true)
echo "tentativa $i: HTTP $code"
[ "$code" = "200" ] && exit 0
sleep 10
done
cat /tmp/ready.json || true
echo "Smoke falhou - rollback para .prev"
if [ -d "${DEPLOY_PATH}.prev" ]; then
sudo rsync -a --delete "${DEPLOY_PATH}.prev/" "$DEPLOY_PATH/"
sudo systemctl restart layoutparser-api
fi
exit 1
8 changes: 7 additions & 1 deletion .github/workflows/ci-dev-local.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,12 @@ name: CI Dev Local - Runner Smoke Test
on:
workflow_dispatch:

# Disparo e sempre manual, mas mantido por paridade/consistencia com os demais workflows
# do repo - evita duas execucoes simultaneas empilhadas se alguem disparar 2x sem querer.
concurrency:
group: ci-dev-local-smoketest
cancel-in-progress: true

permissions:
contents: read

Expand All @@ -24,7 +30,7 @@ jobs:

steps:
- name: Checkout LayoutParserApi
uses: actions/checkout@v7
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1

- name: Confirmar roteamento e ambiente do runner
run: |
Expand Down
26 changes: 13 additions & 13 deletions .github/workflows/ci-dev.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ jobs:

steps:
- name: Checkout LayoutParserApi
uses: actions/checkout@v7
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
path: LayoutParserApi

Expand Down Expand Up @@ -86,25 +86,25 @@ jobs:
# condicional para bin\Debug quando a DLL da configuracao nao existe) - o checkout
# lado a lado e obrigatorio, no mesmo padrao do deploy.yml.
- name: Checkout LayoutParserLib
uses: actions/checkout@v7
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
repository: LayoutParser/LayoutParserLib
path: LayoutParserLib
repository: LayoutParser/layoutparser-lib
path: layoutparser-lib
token: ${{ secrets.GH_PAT_TOKEN || secrets.GITHUB_TOKEN }}
fetch-depth: 1

# O Decrypt e standalone (embute os fontes minimos da Lib) e compila com dotnet build -
# o runner dev-local NAO possui VS Build Tools/msbuild.exe (nao usar setup-msbuild aqui).
- name: Checkout LayoutParserDecrypt
uses: actions/checkout@v7
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
repository: LayoutParser/LayoutParserDecrypt
path: LayoutParserDecrypt
repository: LayoutParser/layoutparser-decrypt
path: layoutparser-decrypt
token: ${{ secrets.GH_PAT_TOKEN || secrets.GITHUB_TOKEN }}
fetch-depth: 1

- name: Setup .NET
uses: actions/setup-dotnet@v6
uses: actions/setup-dotnet@a98b56852c35b8e3190ac28c8c2271da59106c68 # v6.0.0
with:
dotnet-version: '10.0.x'

Expand All @@ -116,7 +116,7 @@ jobs:
# obrigacao de config casada entre Lib e API.
# A Lib e csproj legado (non-SDK) sem PackageReference: o MSBuild do SDK .NET
# compila direto - validado no runner dev-local, que NAO possui VS Build Tools/msbuild.exe.
$LIB_PROJECT = Join-Path $PWD.Path "LayoutParserLib\LayoutParserLib.csproj"
$LIB_PROJECT = Join-Path $PWD.Path "layoutparser-lib\LayoutParserLib.csproj"

if (-not (Test-Path $LIB_PROJECT)) {
Write-Error "Projeto nao encontrado: $LIB_PROJECT"
Expand All @@ -130,7 +130,7 @@ jobs:
exit 1
}

$LIB_DLL = Join-Path $PWD.Path "LayoutParserLib\bin\Debug\LayoutParserLib.dll"
$LIB_DLL = Join-Path $PWD.Path "layoutparser-lib\bin\Debug\LayoutParserLib.dll"
if (-not (Test-Path $LIB_DLL)) {
Write-Error "LayoutParserLib.dll nao foi gerada em: $LIB_DLL"
exit 1
Expand Down Expand Up @@ -303,7 +303,7 @@ jobs:
# seguimos com o binario que ja existir no destino.
- name: Build LayoutParserDecrypt (Release, .NET Framework 4.8.1)
run: |
$DECRYPT_PROJECT = Join-Path $PWD.Path "LayoutParserDecrypt\LayoutParserDecrypt.csproj"
$DECRYPT_PROJECT = Join-Path $PWD.Path "layoutparser-decrypt\LayoutParserDecrypt.csproj"

if (-not (Test-Path $DECRYPT_PROJECT)) {
Write-Warning "Projeto nao encontrado: $DECRYPT_PROJECT - seguindo sem rebuild do Decrypt."
Expand Down Expand Up @@ -505,7 +505,7 @@ jobs:
}

# LayoutParserDecrypt.exe (+ config) - processo externo de descriptografia.
$DECRYPT_BIN = Join-Path $PWD.Path "LayoutParserDecrypt\bin\Release"
$DECRYPT_BIN = Join-Path $PWD.Path "layoutparser-decrypt\bin\Release"
foreach ($f in @('LayoutParserDecrypt.exe', 'LayoutParserDecrypt.exe.config')) {
$p = Join-Path $DECRYPT_BIN $f
if (Test-Path $p) {
Expand All @@ -520,7 +520,7 @@ jobs:
# fallback: copiar da build Debug da Lib se por algum motivo faltar.
$libInDest = Join-Path $API_DEST "LayoutParserLib.dll"
if (-not (Test-Path $libInDest)) {
$libDll = Join-Path $PWD.Path "LayoutParserLib\bin\Debug\LayoutParserLib.dll"
$libDll = Join-Path $PWD.Path "layoutparser-lib\bin\Debug\LayoutParserLib.dll"
if (Test-Path $libDll) {
Copy-Item -Path $libDll -Destination $API_DEST -Force
Write-Host " LayoutParserLib.dll copiada (fallback da build Debug)."
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/config-drift-report.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ jobs:

steps:
- name: Checkout LayoutParserApi
uses: actions/checkout@v7
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
path: LayoutParserApi

Expand Down
21 changes: 15 additions & 6 deletions .github/workflows/dependency-review.yml
Original file line number Diff line number Diff line change
@@ -1,12 +1,21 @@
name: Dependency review

# Bloqueia PR que introduz dependencia (NuGet/npm/etc.) com vulnerabilidade conhecida de
# severidade alta ou critica. Cobre master E develop porque e o nosso fluxo real de PR
# (feat/** -> develop -> master), nao so a branch de release.
# Bloqueia PR que introduz dependencia (NuGet/npm/etc.) com vulnerabilidade conhecida.
# Cobre master E develop porque e o nosso fluxo real de PR (feat/** -> develop -> master),
# nao so a branch de release.
#
# fail-on-severity: moderate - harmonizado com layoutparser-portal (2026-09-25). Nao havia
# justificativa registrada para o "high" anterior (era so a config default copiada quando o
# workflow foi criado, nao uma decisao deliberada de tolerancia a risco) - portanto adotado
# o valor mais rigoroso do portal em vez de documentar excecao sem motivo real.
on:
pull_request:
branches: [ "master", "develop" ]

concurrency:
group: dependency-review-${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

permissions:
contents: read
pull-requests: write
Expand All @@ -16,9 +25,9 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v7
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- name: Dependency Review
uses: actions/dependency-review-action@v5
uses: actions/dependency-review-action@a1d282b36b6f3519aa1f3fc636f609c47dddb294 # v5.0.0
with:
comment-summary-in-pr: always
fail-on-severity: high
fail-on-severity: moderate
78 changes: 78 additions & 0 deletions .github/workflows/deploy-linux.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
name: Deploy API Linux (producao)

# Fase 3 da migracao Linux (issue #578, Epic #575). Pipeline PARALELO ao deploy.yml (Windows).
# Somente workflow_dispatch e com aprovacao: o deploy.yml Windows continua sendo o de producao
# ate o cutover (ver docs/architecture/migracao-linux-fase3-pipeline.md). Rollback = nao usar
# este arquivo e manter o servico Windows.

on:
workflow_dispatch:
inputs:
confirmar:
description: 'Digite DEPLOY-LINUX para confirmar'
required: true

permissions:
contents: read

concurrency:
group: deploy-prod-linux
cancel-in-progress: false

jobs:
deploy:
if: ${{ inputs.confirmar == 'DEPLOY-LINUX' }}
runs-on: [self-hosted, linux, production]
timeout-minutes: 30
env:
DEPLOY_PATH: ${{ vars.DEPLOY_PATH_PROD_LINUX || '/opt/layoutparser-api' }}
API_URL: ${{ vars.API_URL_PROD_LINUX || 'http://localhost:5000' }}
steps:
- uses: actions/checkout@v7
with:
path: layoutparser-api
- uses: actions/checkout@v7
with:
repository: LayoutParser/layoutparser-lib
path: layoutparser-lib
token: ${{ secrets.GH_PAT_TOKEN || secrets.GITHUB_TOKEN }}
fetch-depth: 1
- uses: actions/setup-dotnet@v6
with:
dotnet-version: '10.0.x'

- name: Build LayoutParserLib e testes (quality gate)
run: |
dotnet build layoutparser-lib/LayoutParserLib.csproj --configuration Debug
dotnet test layoutparser-api -c Release --verbosity minimal

- name: Publish
run: dotnet publish layoutparser-api/LayoutParserApi.csproj -c Release -o "$RUNNER_TEMP/publish"

- name: Deploy com backup (systemd)
run: |
set -euo pipefail
test -f /etc/layoutparser-api/secrets.env || { echo "secrets.env ausente"; exit 1; }
sudo rm -rf "${DEPLOY_PATH}.prev"; [ -d "$DEPLOY_PATH" ] && sudo cp -a "$DEPLOY_PATH" "${DEPLOY_PATH}.prev" || true
sudo mkdir -p "$DEPLOY_PATH"
sudo rsync -a --delete "$RUNNER_TEMP/publish/" "$DEPLOY_PATH/"
sudo cp layoutparser-api/deploy/linux/layoutparser-api.service /etc/systemd/system/layoutparser-api.service
sudo systemctl daemon-reload
sudo systemctl enable layoutparser-api
sudo systemctl restart layoutparser-api

- name: Smoke test /health/ready (HTTP 200 estrito) com rollback
run: |
for i in $(seq 1 12); do
code=$(curl -s -o /tmp/ready.json -w '%{http_code}' "$API_URL/health/ready" || true)
echo "tentativa $i: HTTP $code"
[ "$code" = "200" ] && exit 0
sleep 10
done
cat /tmp/ready.json || true
if [ -d "${DEPLOY_PATH}.prev" ]; then
sudo rsync -a --delete "${DEPLOY_PATH}.prev/" "$DEPLOY_PATH/"
sudo systemctl restart layoutparser-api
echo "ROLLBACK aplicado"
fi
exit 1
Loading
Loading