This commit is contained in:
@@ -8,6 +8,7 @@ import (
|
||||
"io"
|
||||
"net/http"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
@@ -22,7 +23,7 @@ import (
|
||||
const (
|
||||
delegatedControlPlaneActor identity.ActorID = "domovoy-control-plane-actor"
|
||||
delegatedControlPlanePrincipal identity.PrincipalID = "domovoy-control-plane-principal"
|
||||
delegatedControlPlaneTokenPath = "/run/secrets/control_plane_service_token"
|
||||
delegatedControlPlaneTokenFile = "control_plane_service_token"
|
||||
)
|
||||
|
||||
type delegatedControlPlaneAuthoritySource interface {
|
||||
@@ -157,13 +158,13 @@ func delegatedControlPlaneCredential() (string, error) {
|
||||
if ref == "" {
|
||||
return "", errors.New("control-plane service credential ref is required")
|
||||
}
|
||||
root := os.Getenv("SECRET_BACKEND_ROOT")
|
||||
root := os.Getenv("CONTROL_PLANE_SERVICE_SECRET_ROOT")
|
||||
if root == "" {
|
||||
root = "/run/secrets"
|
||||
root = "/run/control-plane-secrets"
|
||||
}
|
||||
resolver, err := platformsecrets.NewFileResolver(root)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return resolver.ResolveFile(secretcontracts.SecretFileRef{CredentialRef: secretcontracts.CredentialRef(ref), Purpose: secretcontracts.SecretPurposeServiceAuthentication, Consumer: secretcontracts.RuntimeConsumerCommit, Path: delegatedControlPlaneTokenPath})
|
||||
return resolver.ResolveFile(secretcontracts.SecretFileRef{CredentialRef: secretcontracts.CredentialRef(ref), Purpose: secretcontracts.SecretPurposeServiceAuthentication, Consumer: secretcontracts.RuntimeConsumerCommit, Path: filepath.Join(root, delegatedControlPlaneTokenFile)})
|
||||
}
|
||||
|
||||
@@ -5,6 +5,8 @@ import (
|
||||
"errors"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
@@ -20,6 +22,33 @@ type delegatedAuthorityFake struct {
|
||||
revoked bool
|
||||
}
|
||||
|
||||
func TestDelegatedAuthorityCredentialRotationRejectsOldToken(t *testing.T) {
|
||||
root := t.TempDir()
|
||||
tokenPath := filepath.Join(root, "control_plane_service_token")
|
||||
if err := os.WriteFile(tokenPath, []byte("old-token\n"), 0o600); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
t.Setenv("CONTROL_PLANE_SERVICE_CREDENTIAL_REF", "credential://domovoy/control-plane/service-token/v1")
|
||||
t.Setenv("CONTROL_PLANE_SERVICE_SECRET_ROOT", root)
|
||||
h := delegatedControlPlaneHandler{credential: delegatedControlPlaneCredential}
|
||||
oldRequest := httptest.NewRequest(http.MethodPost, "/v1/internal/control-plane/authorize", nil)
|
||||
oldRequest.Header.Set("Authorization", "Bearer old-token")
|
||||
if !h.serviceAuthenticated(oldRequest) {
|
||||
t.Fatal("active credential was rejected before rotation")
|
||||
}
|
||||
if err := os.WriteFile(tokenPath, []byte("new-token\n"), 0o600); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if h.serviceAuthenticated(oldRequest) {
|
||||
t.Fatal("old credential remained valid after rotation")
|
||||
}
|
||||
newRequest := httptest.NewRequest(http.MethodPost, "/v1/internal/control-plane/authorize", nil)
|
||||
newRequest.Header.Set("Authorization", "Bearer new-token")
|
||||
if !h.serviceAuthenticated(newRequest) {
|
||||
t.Fatal("new credential was rejected after rotation")
|
||||
}
|
||||
}
|
||||
|
||||
func (f *delegatedAuthorityFake) LoadDelegatedControlPlaneGrant(context.Context, authority.GrantID) (authority.DelegatedControlPlaneGrant, error) {
|
||||
if f.grant.ID == "" {
|
||||
return authority.DelegatedControlPlaneGrant{}, errors.New("missing")
|
||||
|
||||
Reference in New Issue
Block a user