Bound durable outbox storage and enforce process writer exclusion
Assistant: codex Assistant-Model: gpt-6-astra Assistant-Session: 01a140c4-354a-7823-8f0d-8f717397f786
This commit is contained in:
parent
2b064eee51
commit
0a05383195
14 changed files with 733 additions and 26 deletions
|
|
@ -334,6 +334,7 @@ func runServe(args []string, stdout, stderr io.Writer) int {
|
|||
signingKeyFile := fs.String("envelope-signing-key-file", "", "owner-mounted base64url Ed25519 seed file")
|
||||
signingKID := fs.String("envelope-signing-kid", "", "independently admitted envelope signing key id")
|
||||
approvalSourceFile := fs.String("approval-source-file", "", "owner fixed Approval HTTPS reader configuration file")
|
||||
outboxMaxBytes := fs.Int64("outbox-max-bytes", emission.MaxOutboxBytes, "bounded outbox payload bytes, maximum67108864")
|
||||
outboxDir := fs.String("outbox-dir", "", "durable emission outbox directory (FLEX-WP-0031); exclusive with --log")
|
||||
emissionSource := fs.String("emission-source", "", "audit-core source name for emitted decision events, e.g. flex-auth.tenant-engine")
|
||||
auditURL := fs.String("audit-url", "", "admitted audit-core /v1/events endpoint; empty disables drain and heartbeats")
|
||||
|
|
@ -378,7 +379,7 @@ func runServe(args []string, stdout, stderr io.Writer) int {
|
|||
}
|
||||
var outbox *emission.Outbox
|
||||
if *outboxDir != "" {
|
||||
outbox, err = emission.Open(*outboxDir, *emissionSource)
|
||||
outbox, err = emission.OpenBounded(*outboxDir, *emissionSource, *outboxMaxBytes)
|
||||
if err != nil {
|
||||
return fail(stderr, err)
|
||||
}
|
||||
|
|
|
|||
58
cmd/access-engine/outbox_capacity_test.go
Normal file
58
cmd/access-engine/outbox_capacity_test.go
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"github.com/netkingdom/access-engine/internal/emission"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestActualHTTPAllEffectsWithheldAtOutboxCapacity(t *testing.T) {
|
||||
engine, err := buildEngine(context.Background(), opsPath("registry_snapshot.json"), opsPath("policy_package.md"), "")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
outbox, err := emission.OpenBounded(t.TempDir(), "synthetic-capacity", 1)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer outbox.Close()
|
||||
engine.SetDecisionLog(outbox)
|
||||
server := httptest.NewServer(newServeMux(engine))
|
||||
defer server.Close()
|
||||
for _, name := range []string{"check_request_allow_adm.json", "check_request_deny_ttl_above_max.json"} {
|
||||
raw, err := os.ReadFile(opsPath(name))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
response, err := http.Post(server.URL+"/v1/check", "application/json", bytes.NewReader(raw))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
body, _ := io.ReadAll(response.Body)
|
||||
response.Body.Close()
|
||||
if response.StatusCode != http.StatusServiceUnavailable || bytes.Contains(body, []byte(`"effect"`)) {
|
||||
t.Fatalf("capacity emitted decision: %d", response.StatusCode)
|
||||
}
|
||||
}
|
||||
status := outbox.Status()
|
||||
if status.CommittedBytes != 0 || status.Pending != 0 {
|
||||
t.Fatal("failed record claimed committed bytes")
|
||||
}
|
||||
for _, count := range status.ReleasedUncommitted {
|
||||
if count != 0 {
|
||||
t.Fatal("withheld effect counted released")
|
||||
}
|
||||
}
|
||||
// An invalid configured cap fails production serve startup before HTTP.
|
||||
var output, errors bytes.Buffer
|
||||
code := run([]string{"serve", "--registry", opsPath("registry_snapshot.json"), "--policy", opsPath("policy_package.md"), "--outbox-dir", filepath.Join(t.TempDir(), "outbox"), "--emission-source", "synthetic-capacity", "--outbox-max-bytes", "67108865"}, &output, &errors)
|
||||
if code == 0 {
|
||||
t.Fatal("source ceiling bypassed at CLI")
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue