Add the enrollment page, move scripts to per-PC credentials, and document the rollout
- Settings > Endpoints > Enrollment. Migration tab: readiness counts and progress, each PC's state with the reasons it is blocked, "Upgrade selected" and "Upgrade next 25", and live wave progress. Credentials tab: enrolled PCs with revoke, pending requests with approve and reject, and the shared key and auto-enroll switches. Turning the shared key off asks for confirmation and shows how many PCs are not enrolled. - The server certificate page shows the SPKI pin to put in the GE-Enforce pin entry. - The agent upgrade script and the asset and printer reporters send the PC's credential when it has one (over https, only to the issuing server), fall back to the shared key, check server pins, and log refusals clearly. - New Set-ShopDBServerPins.ps1 (GE-Enforce entry) and Get-ShopDBServerPin.ps1. - AGENT-CONTRACT.md documents per-PC credentials; the rollout runbook covers phases, gates, rollback, pin and wave entries, and every place the shared key lives and how to clear it at cutover. - Removed the 09-14 certificate design notes and dated session reports, and two VM notes that carried a live collector key and advised plain http. - Corrected the GE-Enforce collector note, which claimed a plain registry token is protected by ACL.
This commit is contained in:
@@ -66,6 +66,24 @@
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="form-group spki-pin">
|
||||
<label>Public key pin (SPKI SHA-256)</label>
|
||||
<p v-if="cert.spkisha256" class="field-hint mono">{{ cert.spkisha256 }}</p>
|
||||
<p v-else class="field-hint">Not reported by this server.</p>
|
||||
<button
|
||||
v-if="cert.spkisha256"
|
||||
class="btn btn-secondary btn-sm"
|
||||
@click="copyPin"
|
||||
>
|
||||
{{ pinCopied ? 'Copied' : 'Copy pin' }}
|
||||
</button>
|
||||
<p class="field-hint">
|
||||
Paste this into the GE-Enforce Set-ShopDBServerPins.ps1 entry
|
||||
(-Pins) so agents 1.20 and later trust only this server's key.
|
||||
It survives a renewal that keeps the same private key.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Issuer</label>
|
||||
<p class="field-hint mono">{{ cert.issuer }}</p>
|
||||
@@ -134,7 +152,11 @@
|
||||
<div class="warning-banner" v-if="cert">
|
||||
<strong>Warning:</strong> Generating a new certificate will replace the current one.
|
||||
Agents using ServerCertThumbprint pinning will reject connections until you update
|
||||
their appsettings.json with the new thumbprint.
|
||||
their appsettings.json with the new thumbprint. A new certificate also has a new
|
||||
key, so agents with ServerPins set will reject it until the pin entry carries the
|
||||
new pin as well. Generating here gives no window to do that; to rotate without an
|
||||
outage, compute the pin of a prepared certificate with Get-ShopDBServerPin.ps1, add
|
||||
it to the pin entry alongside the old one, and upload that certificate below.
|
||||
</div>
|
||||
|
||||
<div class="button-row">
|
||||
@@ -278,6 +300,7 @@ const message = ref('')
|
||||
const error = ref('')
|
||||
const cert = ref(null)
|
||||
const thumbprintCopied = ref(false)
|
||||
const pinCopied = ref(false)
|
||||
|
||||
const generateForm = ref({
|
||||
cn: 'localhost',
|
||||
@@ -405,6 +428,14 @@ function copyThumbprint() {
|
||||
}, 2000)
|
||||
}
|
||||
|
||||
function copyPin() {
|
||||
navigator.clipboard.writeText(cert.value.spkisha256)
|
||||
pinCopied.value = true
|
||||
setTimeout(() => {
|
||||
pinCopied.value = false
|
||||
}, 2000)
|
||||
}
|
||||
|
||||
function formatDate(dateString) {
|
||||
if (!dateString) return 'N/A'
|
||||
const date = new Date(dateString)
|
||||
|
||||
Reference in New Issue
Block a user