Skip to content

robincher/golang-apex-api-security

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

45 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Golang HTTP Signature Signer for APEX

Go Report Card Open Source Love PRs Welcome GuardRails badge

A golang http signature library for APEX. It main purpose is to provide a quick utility that generates HTTP security headers for authenticating with secured APEX endpoints

This library is still in BETA Testing stage

Security Standards

  1. APEX L1 - HMAC256 HTTP Signature
  2. APEX L2 - RSA256 HTTP Signature

Currently still in designing and testing phase

Table of Contents

Getting Started

Installation

go get -u github.com/GovTechSG/golang-apex-api-security

If you have errors about package not found , please verify your GOPATH and ensure your project is residing at the right directory. For more information about setting GOPATH, go here

Walkthrough

Defining the Request Parameters as a struct

// APIParam -  Defining the request struct
type APIParam struct {
	Realm        string `json:"realm"`
	AppID        string `json:"appId"`
	AuthPrefix   string `json:"authPrefix"`
	Secret       string `json:"secret"`
	InvokeURL    string `json:"invokeUrl"`
	SignatureURL string `json:"signatureUrl"`

	HTTPMethod string `json:"httpMethod"`
	Signature  string `json:"signature"`

	PrivateCertFileName string `json:"privateCertFileName"`
	Passphrase          string
	SignatureMethod     string `json:"signatureMethod"`
	Nonce               string `json:"nonce"`
	Timestamp           string `json:"timestamp"`
	Version             string `json:"version"`

	QueryString map[string]interface{} `json:"queryString"`
	FormData    map[string]interface{} `json:"formData"`
}

Invoking the helper utility

Please appened the values based on your own settings and requirements.

requestOpts := APIParam{
		Realm:    "https://portal.example.com,
		AppID: "AppID123",
		AuthPrefix: "apex_lg_l1",
        Secret: "Secret",
        InvokeURL: "https://something.api.gov.sg/v1/resource",
        SignatureURL: ""https://something.api.i.gov.sg/v1/resource""
}

apexAuthHeader, err := getSignatureToken(requestOpts)

Appending to the HTTP header

import net/http example

var req *http.Request
req.Header.Add("Authorization", apexAuthHeader)

Running unit test with coverage

The test data will be pulled from a central package that is shared across all APEX security librares.

You can refer them here

Run the following shell script to pull the test data , execute unit test and print out the test coverage.

./scripts/test_coverage.sh

Request Parameters

This section describes each of the parameters and it purpose.

Mandatory Parameters

  1. AppID

Apex App ID. The App needs to be approved and activated by the API provider. This value can be obtained from the gateway portal.

  1. AuthPrefix

API gateway-specific authorization scheme for a specific gateway zone. Takes 1 of 4 possible values.

var authPrefix = 'Apex_l1_ig';
// or
var authPrefix = 'Apex_l1_eg';
// or
var authPrefix = 'Apex_l2_ig';
// or
var authPrefix = 'Apex_l2_eg';
  1. HTTPMethod

The standard HTTP method required for the target resource

  1. InvokeURL The full API endpoint path that you will be invoking , for example https://my-apex-api.api.gov.sg/api/my/specific/data

IMPORTANT NOTE
Must be the endpoint URL as served from the Apex gateway, from the domain api.gov.sg. This may differ from the actual HTTP endpoint that you are calling, for example if it were behind a proxy with a different URL.**

  1. SignatureURL

The API endpoint that is only internally recognised. For examples : a) https://my-apex-api.i.api.gov.sg/api/my/specific/data b) https://my-apex-api.e.api.gov.sg/api/my/specific/data

We have plans to remove this inconsistency in the near future, so for now do indicate this parameter into the request parameters, else the signature verification will failed.

5a. Secret - For APEX L1 Security

If the API you are accessing is secured with an APEX L1 policy, you need to provide the generated App secret that corresponds to the AppID provided.

5b. PrivateCertFileName andPassphrase` - For APEX L2 Security

If the API you are access is secured with an APEX L2 policy, you need to provide the private key and passphrase corresponding to the public key uploaded for AppID.

var keyPath = "/path/to/my/private.key"
var passphrase = "somepassword"

Optional Parameters

  1. Realm

An identifier for the caller, this can be set to any value. (eg https://portal.example.com)

  1. QueryString / FormData

IMPORTANT NOTE If you pass in the params in QueryString or FormData, please remove the query parameters from both SignatureURL and InvokeURL parameter

2b. QueryString

Object representation of URL query parameters, for the API.

For example, the API endpoint is https://example.com/v1/api?key=value , then you have you pass in the params in this manner below :

var queryString [][]string
queryString = append(queryString, []string{"key", "value"})

2b. FormData

Object representation of form data (x-www-form-urlencoded) passed during HTTP POST / HTTP PUT requests

var formData [][]string
formData = append(formData, []string{"key", "value"})

  1. Nonce An arbitrary string, needs to be different after each successful API call. Defaults to 32 bytes random value encoded in base64.

  2. Timestamp A unix timestamp. Defaults to the current unix timestamp.

Example

Run the example app to see how an authorization token for Apex is constructed

go run example.go

Contributing

For more information about contributing, and raising PRs or issues, see CONTRIBUTING.md.

Release

See CHANGELOG.md.

License

Licensed under the MIT LICENSE

References

About

πŸ”‘ Go helper utility that signs HTTP Authorization Scheme for API authentication

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published