Skip to content

Comments

v4/signer: add codecommit git signing options#628

Open
taraspos wants to merge 1 commit intoaws:mainfrom
taraspos:taras/codecommit-signer
Open

v4/signer: add codecommit git signing options#628
taraspos wants to merge 1 commit intoaws:mainfrom
taraspos:taras/codecommit-signer

Conversation

@taraspos
Copy link

Issue #, if available: aws/aws-sdk-go-v2#3310

Description of changes:
Adds following signer options:

  • DisableUnsignedPayloadSentinel - allows to pass empty request payload without adding automatic UNSIGNED-PAYLOAD placeholder
  • CustomTimeFormat - allows to customize time format used for request signing

Together, those options can be used to sign AWS CodeCommit Git HTTPS requests as described in aws/aws-sdk-go-v2#3310

Example usage
type CodeCommitCredentials struct {
	Username string
	Password string
}

type onlySignHost struct{}

func (r onlySignHost) IsSigned(header string) bool {
	return header == "host"
}

func CodeCommitGitCredentials(ctx context.Context, region, repository string) (CodeCommitCredentials, error) {
	cfg, err := config.LoadDefaultConfig(ctx, config.WithRegion(region))
	if err != nil {
		return CodeCommitCredentials{}, fmt.Errorf("failed to load AWS config: %w", err)
	}

	creds, err := cfg.Credentials.Retrieve(ctx)
	if err != nil {
		return CodeCommitCredentials{}, fmt.Errorf("failed to retrieve credentials: %w", err)
	}

	host := fmt.Sprintf("git-codecommit.%s.amazonaws.com", region)
	path := fmt.Sprintf("https://%s/v1/repos/%s", host, repository)

	req, err := http.NewRequest("GIT", path, nil)
	if err != nil {
		return CodeCommitCredentials{}, fmt.Errorf("failed to create request: %w", err)
	}

	sigTime := time.Now().UTC()

	signer := sigv4.New(func(o *sv4.SignerOptions) {
		o.HeaderRules = onlySignHost{}
		o.DisableUnsignedPayloadSentinel = true
		o.CustomTimeFormat = "20060102T150405"
	})
	signInput := &sigv4.SignRequestInput{
		Request: req,
		Service: "codecommit",
		Region:  region,
		Credentials: scredentials.Credentials{
			AccessKeyID:     creds.AccessKeyID,
			SecretAccessKey: creds.SecretAccessKey,
			SessionToken:    creds.SessionToken,
		},
		Time: sigTime,
	}
	err = signer.SignRequest(signInput)
	if err != nil {
		return CodeCommitCredentials{}, fmt.Errorf("failed to sign request: %w", err)
	}

	username := creds.AccessKeyID + "%" + creds.SessionToken

	authHeader := req.Header.Get("Authorization")
	sigStart := strings.Index(authHeader, "Signature=")
	signature := authHeader[sigStart+10:]
	sigBytes, _ := hex.DecodeString(signature)

	password := sigTime.Format("20060102T150405") + "Z" + hex.EncodeToString(sigBytes)

	return CodeCommitCredentials{
		Username: username,
		Password: password,
	}, nil
}

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant