Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 7 additions & 3 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,25 @@ on:
branches:
- master
pull_request: { }

permissions:
contents: read

jobs:
build:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ ubuntu-latest, windows-latest, macos-latest ]
go: [ '1.23', 'stable' ] # minimum version should be kept in sync with go version in go.mod
go: [ '1.25', 'stable' ] # minimum version should be kept in sync with go version in go.mod
fail-fast: false

name: Go ${{ matrix.go }} ${{ matrix.os }} build

steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v6.0.2
- name: Setup go
uses: actions/setup-go@v5
uses: actions/setup-go@v6.4.0
with:
go-version: ${{ matrix.go }}
- name: Get dependencies
Expand Down
5 changes: 4 additions & 1 deletion .github/workflows/fosstars.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,15 @@ on:
schedule:
- cron: "0 0 * * *"

permissions:
contents: write

jobs:
create_fosstars_report:
runs-on: ubuntu-latest
name: "Security rating"
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v6.0.2
- uses: SAP/fosstars-rating-core-action@v1.14.0
with:
report-branch: fosstars-report
Expand Down
8 changes: 4 additions & 4 deletions .github/workflows/lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,11 @@ jobs:
name: lint
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
- uses: actions/checkout@v6.0.2
- uses: actions/setup-go@v6.4.0
with:
go-version: stable
- name: golangci-lint
uses: golangci/golangci-lint-action@v8
uses: golangci/golangci-lint-action@v9.2.0
with:
version: v2.1.6
version: v2.12.2
7 changes: 5 additions & 2 deletions .github/workflows/reuse.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,14 @@ on:
- master
pull_request: { }

permissions:
contents: read

jobs:
check:
runs-on: ubuntu-latest
name: "Compliance Check"
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v6.0.2
- name: REUSE Compliance Check
uses: fsfe/reuse-action@v5
uses: fsfe/reuse-action@v6
2 changes: 2 additions & 0 deletions .golangci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ linters:
- linters:
- funlen
- goconst
- gosec
- mnd
- revive
path: _test\.go
Expand All @@ -84,6 +85,7 @@ linters:
- third_party$
- builtin$
- examples$
- ^sample/
formatters:
enable:
- gofmt
Expand Down
10 changes: 8 additions & 2 deletions auth/certificate_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,10 @@ func convertToPEM(t *testing.T, derCert string) string {
}

func generateDERCert() string {
key, _ := rsa.GenerateKey(rand.Reader, 512) //nolint:gosec
key, err := rsa.GenerateKey(rand.Reader, 2048)
if err != nil {
panic("generateDERCert: failed to generate RSA key: " + err.Error())
}

issuerName := pkix.Name{
Organization: []string{"my-issuer-org"},
Expand All @@ -89,7 +92,10 @@ func generateDERCert() string {
Subject: issuerName,
Issuer: issuerName,
}
derBytes, _ := x509.CreateCertificate(rand.Reader, &template, &issTemplate, &key.PublicKey, key)
derBytes, err := x509.CreateCertificate(rand.Reader, &template, &issTemplate, &key.PublicKey, key)
if err != nil {
panic("generateDERCert: failed to create certificate: " + err.Error())
}

return base64.StdEncoding.EncodeToString(derBytes)
}
1 change: 1 addition & 0 deletions auth/token.go
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ func (t Token) Email() string {
}

// ZoneID returns "app_tid" claim, if it doesn't exist empty string is returned
//
// Deprecated: is replaced by AppTID and will be removed with the next major release
func (t Token) ZoneID() string {
appTID := t.AppTID()
Expand Down
3 changes: 3 additions & 0 deletions env/iasConfig.go
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ func readCredentialsFileToJSON(serviceInstancePath string, instanceSecretFiles [
for _, instanceSecretFile := range instanceSecretFiles {
if !instanceSecretFile.IsDir() && instanceSecretFile.Name() == iasSecretKeyDefault {
serviceInstanceCredentialsPath := path.Join(serviceInstancePath, instanceSecretFile.Name())
//nolint:gosec // G703: path is built from a trusted K8s service-binding directory
credentials, err := os.ReadFile(serviceInstanceCredentialsPath)
if err != nil {
return nil, fmt.Errorf("cannot read content from '%s': %w", serviceInstanceCredentialsPath, err)
Expand All @@ -150,6 +151,7 @@ func readSecretFilesToJSON(serviceInstancePath string, instanceSecretFiles []os.
}
serviceInstanceSecretPath := path.Join(serviceInstancePath, instanceSecretFile.Name())
var secretContent []byte
//nolint:gosec // G703: path is built from a trusted K8s service-binding directory
secretContent, err := os.ReadFile(serviceInstanceSecretPath)
if err != nil {
return nil, fmt.Errorf("cannot read secret file '%s' from '%s': %w", instanceSecretFile.Name(), serviceInstanceSecretPath, err)
Expand Down Expand Up @@ -190,6 +192,7 @@ func (c DefaultIdentity) GetDomains() []string {
}

// GetZoneUUID implements the env.Identity interface.
//
// Deprecated: is replaced by GetAppTID and will be removed with the next major release
func (c DefaultIdentity) GetZoneUUID() uuid.UUID {
appTid, err := uuid.Parse(c.AppTID)
Expand Down
6 changes: 3 additions & 3 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
module github.com/sap/cloud-security-client-go

go 1.23.0 // should be kept in sync with .github/workflows/build.yml
go 1.25.0 // should be kept in sync with .github/workflows/build.yml

require (
github.com/google/uuid v1.6.0
Expand All @@ -9,8 +9,8 @@ require (
github.com/lestrrat-go/jwx v1.2.31
github.com/patrickmn/go-cache v2.1.0+incompatible
github.com/pquerna/cachecontrol v0.2.0
github.com/stretchr/testify v1.10.0
golang.org/x/sync v0.14.0
github.com/stretchr/testify v1.11.1
golang.org/x/sync v0.20.0
gopkg.in/yaml.v3 v3.0.1
)

Expand Down
4 changes: 4 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,14 @@ github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
golang.org/x/crypto v0.35.0 h1:b15kiHdrGCHrP6LvwaQ3c03kgNhhiMgvlhxHQhmg2Xs=
golang.org/x/crypto v0.35.0/go.mod h1:dy7dXNW32cAb/6/PRuTNsix8T+vJAqvuIy5Bli/x0YQ=
golang.org/x/sync v0.14.0 h1:woo0S4Yywslg6hp4eUFjTVOyKt0RookbpAHG4c1HmhQ=
golang.org/x/sync v0.14.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
golang.org/x/sync v0.20.0 h1:e0PTpb7pjO8GAtTs2dQ6jYa5BWYlMuX047Dco/pItO4=
golang.org/x/sync v0.20.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
Expand Down
15 changes: 11 additions & 4 deletions mocks/mockServer.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,13 @@ import (
//go:embed testdata/privateTestingKey.pem
var dummyKey string

const testKeyID = "testKey"

// dummyMockToken is a fake JWT used by the mock token endpoint for tests.
//
//nolint:gosec // G101: not a real credential, only a fake test fixture
const dummyMockToken = "eyJhbGciOiJIUzI1NiJ9.e30.ZRrHA1JJJW8opsbCGfG_HACGpVUMN_a9IV7pAx_Zmeo"

// MockServer serves as a single tenant OIDC mock server for tests.
// Requests to the MockServer must be done by the mockServers client: MockServer.Server.Client()
type MockServer struct {
Expand Down Expand Up @@ -128,8 +135,8 @@ func (m *MockServer) tokenHandler(w http.ResponseWriter, r *http.Request) {
grantType := r.PostFormValue("grant_type")
clientID := r.PostFormValue("client_id")
if grantType == "client_credentials" && clientID == m.Config.ClientID {
_ = json.NewEncoder(w).Encode(tokenResponse{
Token: "eyJhbGciOiJIUzI1NiJ9.e30.ZRrHA1JJJW8opsbCGfG_HACGpVUMN_a9IV7pAx_Zmeo",
_ = json.NewEncoder(w).Encode(tokenResponse{ //nolint:gosec
Token: dummyMockToken,
})
} else {
w.WriteHeader(http.StatusUnauthorized)
Expand All @@ -140,7 +147,7 @@ func (m *MockServer) tokenHandler(w http.ResponseWriter, r *http.Request) {
func (m *MockServer) JWKsHandler(w http.ResponseWriter, _ *http.Request) {
m.JWKsHitCounter++
key := &JSONWebKey{
Kid: "testKey",
Kid: testKeyID,
Kty: "RSA",
Alg: "RS256",
E: base64.RawURLEncoding.EncodeToString(big.NewInt(int64(m.RSAKey.E)).Bytes()),
Expand Down Expand Up @@ -285,7 +292,7 @@ func (m *MockServer) DefaultHeaders() map[string]interface{} {

header["typ"] = "JWT"
header[headerAlg] = jwa.RS256
header[headerKid] = "testKey"
header[headerKid] = testKeyID

return header
}
Expand Down
2 changes: 1 addition & 1 deletion tokenclient/tokenFlows_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import (
)

var tokenRequestHandlerHitCounter int
var dummyToken = "eyJhbGciOiJIUzI1NiJ9.e30.ZRrHA1JJJW8opsbCGfG_HACGpVUMN_a9IV7pAx_Zmeo" //nolint:gosec
var dummyToken = "eyJhbGciOiJIUzI1NiJ9.e30.ZRrHA1JJJW8opsbCGfG_HACGpVUMN_a9IV7pAx_Zmeo"

var clientSecretConfig = &env.DefaultIdentity{
ClientID: "09932670-9440-445d-be3e-432a97d7e2ef",
Expand Down
Loading