Implement inbound caller authentication (ADR 0004); close T03 and T05
TokenReview-based caller identity with audience-scoped tokens and exact resource.system to ServiceAccount bindings, per ops-warden's recommendation. Deletes the unwired tenant-engine live-roles adapter (T03) and adds make verify-posture (T05). Source implements A2; running digest is still A0 until promotion, so tenancy.current.A stays 0. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
parent
6d82ef7f14
commit
1e1e077b27
18 changed files with 768 additions and 357 deletions
|
|
@ -11,6 +11,7 @@ import (
|
|||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/netkingdom/flex-auth/internal/callerauth"
|
||||
"github.com/netkingdom/flex-auth/pkg/api"
|
||||
)
|
||||
|
||||
|
|
@ -157,6 +158,77 @@ func TestServeOpsWardenCheckContract(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
type fixedTokenReviewer struct {
|
||||
identity callerauth.Identity
|
||||
}
|
||||
|
||||
func (r fixedTokenReviewer) Review(context.Context, string) (callerauth.Identity, error) {
|
||||
return r.identity, nil
|
||||
}
|
||||
|
||||
func TestServeCallerAuthenticationBindsSystemToPrincipal(t *testing.T) {
|
||||
engine, err := buildEngine(context.Background(), opsPath("registry_snapshot.json"), opsPath("policy_package.md"), "")
|
||||
if err != nil {
|
||||
t.Fatalf("buildEngine: %v", err)
|
||||
}
|
||||
authenticator, err := callerauth.New(callerauth.ModeEnforce, fixedTokenReviewer{identity: callerauth.Identity{
|
||||
Username: "system:serviceaccount:ops-warden:ops-warden",
|
||||
Audiences: []string{"flex-auth"},
|
||||
}}, "flex-auth", map[string]string{
|
||||
"ops-warden": "system:serviceaccount:ops-warden:ops-warden",
|
||||
}, nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
server := httptest.NewServer(newServeMuxWithCallerAuth(engine, authenticator))
|
||||
defer server.Close()
|
||||
body, err := os.ReadFile(opsPath("check_request_allow_adm.json"))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
request, _ := http.NewRequest(http.MethodPost, server.URL+"/v1/check", bytes.NewReader(body))
|
||||
request.Header.Set("content-type", "application/json")
|
||||
resp, err := http.DefaultClient.Do(request)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
resp.Body.Close()
|
||||
if resp.StatusCode != http.StatusUnauthorized {
|
||||
t.Fatalf("missing token status = %d; want 401", resp.StatusCode)
|
||||
}
|
||||
|
||||
request, _ = http.NewRequest(http.MethodPost, server.URL+"/v1/check", bytes.NewReader(body))
|
||||
request.Header.Set("content-type", "application/json")
|
||||
request.Header.Set("authorization", "Bearer workload-token")
|
||||
resp, err = http.DefaultClient.Do(request)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
resp.Body.Close()
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
t.Fatalf("bound caller status = %d; want 200", resp.StatusCode)
|
||||
}
|
||||
|
||||
wrong, _ := callerauth.New(callerauth.ModeEnforce, fixedTokenReviewer{identity: callerauth.Identity{
|
||||
Username: "system:serviceaccount:another:caller",
|
||||
Audiences: []string{"flex-auth"},
|
||||
}}, "flex-auth", map[string]string{"ops-warden": "system:serviceaccount:ops-warden:ops-warden"}, nil)
|
||||
wrongServer := httptest.NewServer(newServeMuxWithCallerAuth(engine, wrong))
|
||||
defer wrongServer.Close()
|
||||
request, _ = http.NewRequest(http.MethodPost, wrongServer.URL+"/v1/check", bytes.NewReader(body))
|
||||
request.Header.Set("content-type", "application/json")
|
||||
request.Header.Set("authorization", "Bearer workload-token")
|
||||
resp, err = http.DefaultClient.Do(request)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
resp.Body.Close()
|
||||
if resp.StatusCode != http.StatusForbidden {
|
||||
t.Fatalf("mismatched caller status = %d; want 403", resp.StatusCode)
|
||||
}
|
||||
}
|
||||
|
||||
func TestRunLoadRegistryOpsWardenProduction(t *testing.T) {
|
||||
var stdout, stderr bytes.Buffer
|
||||
code := run([]string{"load-registry", "--file", opsPath("production_registry_snapshot.json")}, &stdout, &stderr)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue