Introdução
Uma entrega verificada só é útil se esses bytes verificados se tornarem a versão em execução. A Waymark precisa de um receptor reutilizável que recuse um pacote não aprovado antes de alterar seu guia de passeios do festival.
Você substituirá um pequeno script de shell, exercitará suas decisões de rejeição e publicará a atualização solicitada pelo organizador. Este ambiente independente começa com o guia original e seus próprios pacotes. O laboratório guiado anterior ensinou assinaturas, chaves confiáveis de forma independente, metadados solicitados e resumos de arquivos. Agora você os combinará sem precisar programar em Python.
Entenda o Guia em Funcionamento e o Contrato do Receptor
Nesta etapa, você identificará o que a atualização deve mudar e o que deve preservar. Abra Event Guide e depois Old Mill Walk. A edição original de event-guide é 2.0 e o encontro do passeio é às 11:00. Use All walks para voltar e baixe a planilha de trajetos. Tanto a página de detalhes quanto o download devem funcionar após a atualização.
A página inicial do guia identifica a edição acima do título e mostra o horário de encontro de cada passeio no respectivo cartão:

Mude para Workspace. cd muda o diretório; este caminho absoluto funciona de qualquer local:
cd /home/labex/project/waymark
cat exibe arquivos. Leia a solicitação de atualização fornecida de forma independente:
cat /opt/labex-waymark/trust/request.json
Ela solicita o produto event-guide, versão 2.1. Sua atualização aprovada muda Old Mill Walk para 14:00. O outro passeio permanece às 09:30. Leia o script inicial:
cat receive.sh
O script inicial obtém um resumo do próprio pacote e o passa ao publicador. Outro publicador poderia fornecer um manifesto e um arquivo correspondentes. Este script ainda não verifica uma assinatura nem o produto/versão solicitados pelo organizador. Você o substituirá antes de publicar.
A interface exigida é:
bash receive.sh CANDIDATE_DIRECTORY DESTINATION_DIRECTORY
O primeiro argumento é um pacote do fornecedor. O segundo é um diretório de publicação do guia; no projeto em execução, ele é published. Os dois caminhos podem ser absolutos ou relativos, ser renomeados e conter espaços. Não fixe um rótulo de pacote nem o destino no código. Uma atualização bem-sucedida retorna zero. A rejeição retorna um valor diferente de zero e mantém todos os arquivos de publicação existentes inalterados. Uma atualização legítima mantém as versões anteriores e os uploads não relacionados.
Você pode editar receive.sh e criar arquivos temporários. Mantenha inalterados os pacotes originais, a chave/solicitação independentes, o publicador preparado e os demais arquivos de execução. O receptor deve funcionar a partir de outro diretório quando copiado sozinho, com as mesmas ferramentas preparadas e os arquivos de confiança independentes disponíveis. A avaliação exercita esse contrato em diretórios descartáveis, além de verificar o guia real.
Se digitar um caminho incorretamente, execute o cd absoluto acima, use ls candidates para conferir os rótulos e tente o comando novamente. Uma verificação malsucedida é motivo para inspecionar a evidência pertinente, não para reinicializar o ambiente.
Projete um Receptor que Pare Antes de Publicar
Nesta etapa, você entenderá o pequeno script antes de escrevê-lo. Permaneça em Workspace.
O receptor copiará os três arquivos relacionados para um diretório temporário privado, verificará o manifesto copiado, comparará seu produto/versão com a solicitação independente e passará o arquivo compactado copiado junto com o resumo assinado a um publicador preparado. Ele nunca verificará um candidato para depois reabrir um caminho de candidato diferente para a entrega.
O publicador /opt/labex-waymark/publish.py é um código preparado para lidar com arquivos compactados. Ele lê o arquivo fornecido em um único buffer de bytes, verifica esse buffer com o resumo fornecido, extrai com segurança apenas site.json e routes.csv e publica esses mesmos bytes. Preserva as versões anteriores e uploads/. Ele não decide em qual assinatura confiar nem qual produto/versão o organizador solicitou; essas decisões pertencem ao seu receptor.
Você usará estes recursos do shell:
#!/bin/bashidentifica o shell do script. Executarbash receive.shtambém seleciona Bash explicitamente.set -euo pipefailfaz um comando malsucedido não tratado, uma variável não definida ou um pipeline malsucedido interromperem o script. Uma assinatura inválida nunca deve deixar a execução continuar até a publicação.$1e$2são os dois argumentos.candidate=$1salva um valor;"$candidate"o expande como um único argumento, incluindo espaços.$#conta os argumentos, e[ "$#" -ne 2 ]testa se essa contagem é diferente de dois.if,thenefidelimitam o bloco condicional.$(command)salva a saída de um comando.mktemp -dcria um diretório temporário exclusivo.trap '...' EXITexecuta a limpeza quando o script termina. Aqui,rm -rf -- "$stage"remove apenas esse diretório temporário gerado; nunca o substitua pelo diretório do projeto.--encerra a interpretação de opções para que um caminho seja tratado como dado.cp -- SOURCE SOURCE SOURCE DIRECTORY/copia os três arquivos. A barra final identifica o diretório de destino.jq -r .product FILElê uma string JSON sem as aspas do JSON.jq -eretorna um status de falha para um resultado falso.--arg product "$product"fornece ao filtro uma variável de string chamada$product.andexige que todas as condições sejam verdadeiras. Aspas simples preservam o texto do filtro para jq.> /dev/nulldescarta o booleano exibido, mantendo seu status de saída.echo ... >&2escreve um erro no fluxo de erros;exit 2encerra com um status diferente de zero.
O comando de assinatura usa a mesma chave pública fixada de forma independente do laboratório anterior. Seu --bundle aponta para o bundle de assinatura copiado, e seu último argumento é o manifesto copiado. --insecure-ignore-tlog é a limitação explícita desses dados sintéticos offline: ignora a verificação do registro público, mas ainda verifica a assinatura com a chave fixada. Este receptor não é um verificador de identidade pública ou de registro de transparência.
O comando Python final chama o publicador preparado; você não está escrevendo Python. Ele recebe o arquivo copiado, o resumo do manifesto verificado e o destino solicitado. Se o resumo não corresponder aos bytes do arquivo, ele recusa a atualização antes de tocar no guia existente.
Salve o Receptor Reutilizável
Nesta etapa, você escreverá o receptor usando os mecanismos que acabou de examinar. Comece em Workspace, em /home/labex/project/waymark.
O comando a seguir substitui receive.sh. cat > receive.sh redireciona o texto fornecido para o arquivo. <<'RECEIVER' inicia um here-document: tudo até a linha contendo apenas RECEIVER se torna conteúdo do arquivo. Colocar esse marcador entre aspas preserva $1, $stage e as variáveis jq para a execução posterior do script. Cole o bloco completo, incluindo o marcador final:
cat > receive.sh <<'RECEIVER'
#!/bin/bash
set -euo pipefail
if [ "$#" -ne 2 ]; then
echo "Usage: bash receive.sh CANDIDATE_DIRECTORY DESTINATION_DIRECTORY" >&2
exit 2
fi
candidate=$1
destination=$2
stage=$(mktemp -d)
trap 'rm -rf -- "$stage"' EXIT
cp -- "$candidate/manifest.json" "$candidate/manifest.sigstore.json" "$candidate/guide.tar.gz" "$stage/"
/opt/labex-waymark/bin/cosign verify-blob --key /opt/labex-waymark/trust/publisher.pub --bundle "$stage/manifest.sigstore.json" --insecure-ignore-tlog "$stage/manifest.json"
product=$(jq -r .product /opt/labex-waymark/trust/request.json)
version=$(jq -r .version /opt/labex-waymark/trust/request.json)
jq -e --arg product "$product" --arg version "$version" '.product == $product and .version == $version and .archive == "guide.tar.gz"' "$stage/manifest.json" > /dev/null
digest=$(jq -r .sha256 "$stage/manifest.json")
python3 /opt/labex-waymark/publish.py "$stage/guide.tar.gz" "$digest" "$destination"
RECEIVER
Leia o arquivo salvo:
cat receive.sh
Confirme que a chave pública e a solicitação vêm de /opt/labex-waymark/trust/, enquanto o manifesto, o bundle e o arquivo compactado vêm todos de "$stage". Observe que o diretório do candidato original não é lido novamente após a cópia. Alterar ou renomear a entrega do fornecedor depois dessa cópia não pode trocar os bytes encaminhados ao publicador.
Se o terminal mostrar um prompt de continuação porque o marcador final foi omitido, digite RECEIVER em uma linha separada e pressione Enter. Se o arquivo foi colado incorretamente, repita todo o here-document; isso substitui apenas receive.sh. Não execute um receptor incompleto.
A verificação de política preparada executa seu script sem alterações como uma conta comum em diretórios de publicação descartáveis. Ela verifica os arquivos efetivamente publicados, os casos rejeitados e o comportamento de preservação; não procura uma grafia específica de comando:
sudo python3 /opt/labex-waymark/verify.py policy
sudo é necessário para essa verificação preparada executar a conta comum isolada, não para seu receptor. A verificação deixa o guia em execução intacto. Espere que sua última linha diga que o guia assinado solicitado é aceito e os quatro casos não aprovados são recusados. Se falhar, inspecione a decisão relatada e corrija receive.sh antes de continuar.
Observe as Rejeições Antes de Atualizar o Guia em Produção
Nesta etapa, você confirmará que o receptor para em três falhas diferentes enquanto o guia original permanece disponível. Comece em Workspace, em /home/labex/project/waymark.
Primeiro, tente o pacote assinado por outro publicador. Espere um erro de verificação de assinatura e um status diferente de zero:
bash receive.sh candidates/parcel-102 published
$? contém o status de saída do comando imediatamente anterior. Leia-o antes de executar qualquer outra coisa:
echo $?
Agora tente a edição autêntica, mas anterior. Espere que a verificação de assinatura passe, seguida de um status diferente de zero porque a comparação de produto/versão solicitados é falsa:
bash receive.sh candidates/parcel-101 published
echo $?
A comparação jq é deliberadamente silenciosa; o status diferente de zero registra sua rejeição. Uma assinatura válida não se sobrepôs à solicitação independente.
Por fim, tente o arquivo alterado. Espere que a assinatura passe, mas que o publicador informe uma divergência de resumo e mantenha o guia existente:
bash receive.sh candidates/parcel-103 published
echo $?
Mude para Event Guide e atualize a página. O guia ainda deve ser a edição 2.0; Old Mill Walk ainda deve ter encontro às 11:00. Use All walks para voltar, baixe a planilha de trajetos e abra Visitor notice. Um receptor que recusasse tudo também preservaria esse guia antigo; por isso uma atualização legítima bem-sucedida também é exigida.
Um arquivo ausente ou um erro de conexão não equivale a essas rejeições de política esperadas. Para um caminho de pacote digitado incorretamente, volte ao caminho absoluto da área de trabalho, liste candidates e tente novamente. Se o site estiver indisponível, inspecione o erro relatado; não o considere uma recusa bem-sucedida.
Publique e Use o Novo Guia Aprovado
Nesta etapa, você entregará a atualização verificada e usará suas páginas e seu download reais. Comece em Workspace, em /home/labex/project/waymark.
Receba o pacote aprovado:
bash receive.sh candidates/parcel-104 published
Espere Verified OK e:
Published event-guide 2.1. Previous releases and uploads kept.
Confira seu status imediatamente:
echo $?
Espere 0. Mude para Event Guide e atualize a página. A página inicial agora mostra a edição 2.1 de event-guide. Abra Old Mill Walk e confirme 14:00; depois use All walks e abra Riverside Welcome para confirmar que seu encontro às 09:30 foi preservado. Volte com All walks e baixe a nova planilha de trajetos. As duas linhas devem concordar com as páginas de detalhes. Abra Visitor notice para confirmar que as orientações originais permanecem.
A página inicial aprovada mostra a edição 2.1; observe o horário de encontro de Old Mill Walk às 14:00:

Mude para Workspace. A autoverificação do serviço lê a página de detalhes em execução, os bytes da planilha de trajetos baixada, os arquivos atuais do guia, a versão anterior preservada e o aviso:
python3 /opt/labex-waymark/verify.py live
Espere:
The running guide and download match the approved release. Previous releases and visitor notice are preserved.
ls lista os diretórios das versões mantidas:
ls published/releases
Deve haver uma versão anterior event-guide-2.0-... e a nova versão event-guide-2.1-.... Os caracteres finais vêm do resumo real do arquivo e não são valores para memorizar.
Se a verificação do serviço falhar, use sua mensagem para distinguir uma decisão de recebimento de um site indisponível ou de um arquivo original alterado. Corrija o receptor se necessário e receba novamente o pacote aprovado original. Repetir a mesma atualização válida é seguro: o publicador reutiliza a versão idêntica e mantém os arquivos anteriores. Repita a autoverificação do serviço para confirmar o resultado.
Resumo
Você substituiu um receptor que confiava em sua entrega por um que verifica uma chave de publicador e uma solicitação do organizador independentes, e então vincula o resumo assinado do arquivo aos bytes efetivamente publicados. Signatários incorretos, versões antigas autênticas e arquivos alterados foram recusados enquanto o serviço original continuou utilizável.
A atualização aprovada agora é um guia real com páginas de detalhes funcionais e um download de trajetos correspondente. O desafio aplica essas mesmas ferramentas a um guia acessível e inclui um pacote com assinatura autêntica para o produto errado.


