mirror of
https://github.com/zitadel/zitadel.git
synced 2025-08-11 19:07:30 +00:00
feat: action v2 signing (#8779)
# Which Problems Are Solved The action v2 messages were didn't contain anything providing security for the sent content. # How the Problems Are Solved Each Target now has a SigningKey, which can also be newly generated through the API and returned at creation and through the Get-Endpoints. There is now a HTTP header "Zitadel-Signature", which is generated with the SigningKey and Payload, and also contains a timestamp to check with a tolerance if the message took to long to sent. # Additional Changes The functionality to create and check the signature is provided in the pkg/actions package, and can be reused in the SDK. # Additional Context Closes #7924 --------- Co-authored-by: Livio Spring <livio.a@gmail.com>
This commit is contained in:
@@ -11,6 +11,7 @@ import (
|
||||
sq "github.com/Masterminds/squirrel"
|
||||
|
||||
"github.com/zitadel/zitadel/internal/api/authz"
|
||||
"github.com/zitadel/zitadel/internal/crypto"
|
||||
"github.com/zitadel/zitadel/internal/database"
|
||||
"github.com/zitadel/zitadel/internal/domain"
|
||||
"github.com/zitadel/zitadel/internal/query/projection"
|
||||
@@ -175,6 +176,11 @@ func (q *Queries) TargetsByExecutionID(ctx context.Context, ids []string) (execu
|
||||
instanceID,
|
||||
database.TextArray[string](ids),
|
||||
)
|
||||
for i := range execution {
|
||||
if err := execution[i].decryptSigningKey(q.targetEncryptionAlgorithm); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return execution, err
|
||||
}
|
||||
|
||||
@@ -205,6 +211,11 @@ func (q *Queries) TargetsByExecutionIDs(ctx context.Context, ids1, ids2 []string
|
||||
database.TextArray[string](ids1),
|
||||
database.TextArray[string](ids2),
|
||||
)
|
||||
for i := range execution {
|
||||
if err := execution[i].decryptSigningKey(q.targetEncryptionAlgorithm); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return execution, err
|
||||
}
|
||||
|
||||
@@ -352,6 +363,8 @@ type ExecutionTarget struct {
|
||||
Endpoint string
|
||||
Timeout time.Duration
|
||||
InterruptOnError bool
|
||||
signingKey *crypto.CryptoValue
|
||||
SigningKey string
|
||||
}
|
||||
|
||||
func (e *ExecutionTarget) GetExecutionID() string {
|
||||
@@ -372,6 +385,21 @@ func (e *ExecutionTarget) GetTargetType() domain.TargetType {
|
||||
func (e *ExecutionTarget) GetTimeout() time.Duration {
|
||||
return e.Timeout
|
||||
}
|
||||
func (e *ExecutionTarget) GetSigningKey() string {
|
||||
return e.SigningKey
|
||||
}
|
||||
|
||||
func (t *ExecutionTarget) decryptSigningKey(alg crypto.EncryptionAlgorithm) error {
|
||||
if t.signingKey == nil {
|
||||
return nil
|
||||
}
|
||||
keyValue, err := crypto.DecryptString(t.signingKey, alg)
|
||||
if err != nil {
|
||||
return zerrors.ThrowInternal(err, "QUERY-bxevy3YXwy", "Errors.Internal")
|
||||
}
|
||||
t.SigningKey = keyValue
|
||||
return nil
|
||||
}
|
||||
|
||||
func scanExecutionTargets(rows *sql.Rows) ([]*ExecutionTarget, error) {
|
||||
targets := make([]*ExecutionTarget, 0)
|
||||
@@ -386,6 +414,7 @@ func scanExecutionTargets(rows *sql.Rows) ([]*ExecutionTarget, error) {
|
||||
endpoint = &sql.NullString{}
|
||||
timeout = &sql.NullInt64{}
|
||||
interruptOnError = &sql.NullBool{}
|
||||
signingKey = &crypto.CryptoValue{}
|
||||
)
|
||||
|
||||
err := rows.Scan(
|
||||
@@ -396,6 +425,7 @@ func scanExecutionTargets(rows *sql.Rows) ([]*ExecutionTarget, error) {
|
||||
endpoint,
|
||||
timeout,
|
||||
interruptOnError,
|
||||
signingKey,
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
@@ -409,6 +439,7 @@ func scanExecutionTargets(rows *sql.Rows) ([]*ExecutionTarget, error) {
|
||||
target.Endpoint = endpoint.String
|
||||
target.Timeout = time.Duration(timeout.Int64)
|
||||
target.InterruptOnError = interruptOnError.Bool
|
||||
target.signingKey = signingKey
|
||||
|
||||
targets = append(targets, target)
|
||||
}
|
||||
|
Reference in New Issue
Block a user