mirror of
https://github.com/seaweedfs/seaweedfs.git
synced 2026-10-30 00:40:44 +01:00
* iam: evaluate trust policies deny-by-default EvaluateTrustPolicy seeded its result with the engine's DefaultEffect, so a non-matching trust-policy statement set still resolved to Allow when the IAM config sets policy.defaultEffect=Allow. A caller holding a validly signed token from a registered provider could then assume a role its trust policy does not admit. Trust policies now start from implicit deny, matching AWS semantics and the pre-d751623 behavior of evaluateTrustPolicy; DefaultEffect still governs identity-policy evaluation. Upgrade note: deployments on defaultEffect=Allow whose trust policies do not match their callers will see those assumptions refused. Generated with [Devin](https://devin.ai) Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com> * iam: cover trust policy implicit deny under DefaultEffect=Allow Generated with [Devin](https://devin.ai) Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com> --------- Co-authored-by: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
81 lines
3.1 KiB
Go
81 lines
3.1 KiB
Go
package policy
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"testing"
|
|
)
|
|
|
|
const subjectBoundTrustPolicy = `{"Version":"2012-10-17","Statement":[{"Effect":"Allow",
|
|
"Principal":{"Federated":"https://oidc.example"},"Action":["sts:AssumeRoleWithWebIdentity"],
|
|
"Condition":{"StringEquals":{"oidc:sub":"spiffe://example.org/ns/app/sa/app"}}}]}`
|
|
|
|
func webIdentityContext(sub string) *EvaluationContext {
|
|
return &EvaluationContext{
|
|
Principal: "web-identity-user",
|
|
Action: "sts:AssumeRoleWithWebIdentity",
|
|
Resource: "arn:aws:iam::role/app",
|
|
RequestContext: map[string]interface{}{
|
|
"aws:FederatedProvider": "https://oidc.example",
|
|
"oidc:iss": "https://oidc.example",
|
|
"oidc:sub": sub,
|
|
},
|
|
}
|
|
}
|
|
|
|
// A trust policy is deny-by-default. The engine's DefaultEffect decides
|
|
// requests no identity policy speaks to; it must not let a principal the trust
|
|
// policy does not allow assume the role.
|
|
func TestEvaluateTrustPolicyIsImplicitDenyWhateverTheDefaultEffect(t *testing.T) {
|
|
var trust PolicyDocument
|
|
if err := json.Unmarshal([]byte(subjectBoundTrustPolicy), &trust); err != nil {
|
|
t.Fatalf("parse test trust policy: %v", err)
|
|
}
|
|
for _, defaultEffect := range []string{"Allow", "Deny"} {
|
|
t.Run("defaultEffect="+defaultEffect, func(t *testing.T) {
|
|
engine := NewPolicyEngine()
|
|
if err := engine.Initialize(&PolicyEngineConfig{DefaultEffect: defaultEffect, StoreType: "memory"}); err != nil {
|
|
t.Fatalf("initialize policy engine: %v", err)
|
|
}
|
|
|
|
res, err := engine.EvaluateTrustPolicy(context.Background(), &trust, webIdentityContext("spiffe://example.org/ns/other/sa/x"))
|
|
if err != nil {
|
|
t.Fatalf("evaluate trust policy: %v", err)
|
|
}
|
|
if res.Effect != EffectDeny {
|
|
t.Errorf("a subject the trust policy does not allow got %s", res.Effect)
|
|
}
|
|
|
|
res, err = engine.EvaluateTrustPolicy(context.Background(), &trust, webIdentityContext("spiffe://example.org/ns/app/sa/app"))
|
|
if err != nil {
|
|
t.Fatalf("evaluate trust policy: %v", err)
|
|
}
|
|
if res.Effect != EffectAllow {
|
|
t.Errorf("the subject the trust policy allows got %s", res.Effect)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestEvaluateTrustPolicyExplicitDenyWins(t *testing.T) {
|
|
var trust PolicyDocument
|
|
doc := `{"Version":"2012-10-17","Statement":[
|
|
{"Effect":"Allow","Principal":{"Federated":"https://oidc.example"},"Action":["sts:AssumeRoleWithWebIdentity"]},
|
|
{"Effect":"Deny","Principal":{"Federated":"https://oidc.example"},"Action":["sts:AssumeRoleWithWebIdentity"],
|
|
"Condition":{"StringEquals":{"oidc:sub":"spiffe://example.org/ns/app/sa/app"}}}]}`
|
|
if err := json.Unmarshal([]byte(doc), &trust); err != nil {
|
|
t.Fatalf("parse test trust policy: %v", err)
|
|
}
|
|
engine := NewPolicyEngine()
|
|
if err := engine.Initialize(&PolicyEngineConfig{DefaultEffect: "Allow", StoreType: "memory"}); err != nil {
|
|
t.Fatalf("initialize policy engine: %v", err)
|
|
}
|
|
res, err := engine.EvaluateTrustPolicy(context.Background(), &trust, webIdentityContext("spiffe://example.org/ns/app/sa/app"))
|
|
if err != nil {
|
|
t.Fatalf("evaluate trust policy: %v", err)
|
|
}
|
|
if res.Effect != EffectDeny {
|
|
t.Errorf("explicit Deny did not win: %s", res.Effect)
|
|
}
|
|
}
|