Skip to content

Commit

Permalink
Merge branch 'master' into token-introspection
Browse files Browse the repository at this point in the history
  • Loading branch information
johakoch authored May 8, 2024
2 parents 2bf8b4d + 68ec1fb commit 837d989
Show file tree
Hide file tree
Showing 173 changed files with 8,767 additions and 3,995 deletions.
4 changes: 1 addition & 3 deletions .github/workflows/docker.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ on:
paths-ignore:
- '**/README.md'
- '.github/workflows/weekly-fuzz.yml'
- 'docs/**'
release:
types: [ published ]
workflow_dispatch:
Expand Down Expand Up @@ -73,9 +74,6 @@ jobs:
- image: 'coupergateway/couper'
username_key: DOCKER_COUPER_GATEWAY_USERNAME
password_key: DOCKER_COUPER_GATEWAY_PASSWORD
- image: 'avenga/couper' # TODO: remove later
username_key: DOCKER_USERNAME
password_key: DOCKER_PASSWORD
steps:
- name: checkout
uses: actions/checkout@v4
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/go.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ on:
paths-ignore:
- '**/README.md'
- '.github/workflows/weekly-fuzz.yml'
- 'docs/**'
pull_request:

jobs:
Expand Down
3 changes: 3 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,9 @@ jobs:
with:
go-version: '1.21'

- name: Set GOARCH environment variable
run: echo "GOARCH=${{ matrix.goarch }}" >> $GITHUB_ENV

- name: 'import certificate'
env:
BUILD_CERTIFICATE_BASE64: ${{ secrets.MACOS_CERTIFICATE_BASE64 }}
Expand Down
30 changes: 30 additions & 0 deletions .github/workflows/weekly-trivy.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
name: trivy
on:
schedule:
- cron: '0 9 * * 1' # monday
workflow_dispatch:
pull_request:
jobs:
build:
name: Build
runs-on: ubuntu-22.04
permissions:
# required for all workflows
security-events: write
steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Run Trivy vulnerability scanner in repo mode
uses: aquasecurity/trivy-action@master
with:
scan-type: 'fs'
ignore-unfixed: true
format: 'sarif'
output: 'trivy-results.sarif'
severity: 'CRITICAL,HIGH'

- name: Upload Trivy scan results to GitHub Security tab
uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: 'trivy-results.sarif'
65 changes: 40 additions & 25 deletions .npm/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions .npm/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@
},
"main": "couper-binary.js",
"dependencies": {
"axios": "^1.6.0",
"tar": "^6.1.11",
"axios": "^1.6.8",
"tar": "^6.2.1",
"unzip-stream": "^0.3.1"
}
}
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ Unreleased changes are available as `coupergateway/couper:edge` container.
* [`Server-Timing` header](https://docs.couper.io/configuration/block/settings) only reporting last requests/proxies of [endpoint sequences](https://docs.couper.io/configuration/block/endpoint#endpoint-sequence) ([#751](https://github.com/coupergateway/couper/pull/751))
* Selecting of appropriate [error handler](https://docs.couper.io/configuration/block/error_handler) in two cases ([#753](https://github.com/coupergateway/couper/pull/753))
* Storing of digit-starting string object keys in [request context](https://docs.couper.io/configuration/variables#request) and of digit-starting string header field names in [request](https://docs.couper.io/configuration/variables#request) variable ([#799](https://github.com/coupergateway/couper/pull/799))
* Use of boolean values for the `headers` attribute or [modifiers](https://docs.couper.io/configuration/modifiers) ([#805](https://github.com/coupergateway/couper/pull/805))
* Duplicate [CORS](https://docs.couper.io/configuration/block/cors) response headers (with backend sending CORS response headers, too) ([#804](https://github.com/coupergateway/couper/pull/804))

* **Dependencies**
* build with go 1.21 ([#800](https://github.com/coupergateway/couper/pull/800))
Expand Down
2 changes: 1 addition & 1 deletion DOCKER.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ $ docker run coupergateway/couper run -watch -p 8081
| COUPER_WATCH_RETRIES | `5` | Maximal retry count for configuration reloads which could not bind the configured port. |
| COUPER_WATCH_RETRY_DELAY | `500ms` | Delay duration before next attempt if an error occurs. |

### Oberservation Environment Variables
### Observation Environment Variables

| Variable | Default | Description |
|:-------------------------------------|:----------------------------------------------------------|:--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
Expand Down
5 changes: 3 additions & 2 deletions accesscontrol/jwt.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (
"time"

"github.com/golang-jwt/jwt/v5"
"github.com/google/go-cmp/cmp"
"github.com/hashicorp/hcl/v2"
"github.com/sirupsen/logrus"

Expand Down Expand Up @@ -372,8 +373,8 @@ func (j *JWT) validateClaims(tokenClaims jwt.MapClaims, expectedClaims map[strin
continue
}

if val != v {
return fmt.Errorf("unexpected value for claim %s, got %q, expected %q", k, val, v)
if diff := cmp.Diff(v, val); diff != "" {
return fmt.Errorf("unexpected value for claim %s, got %#v, expected %#v", k, val, v)
}
}
return nil
Expand Down
128 changes: 128 additions & 0 deletions accesscontrol/jwt_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -368,6 +368,134 @@ func Test_JWT_Validate(t *testing.T) {
}
}

func Test_JWT_Validate_claims(t *testing.T) {
log, _ := test.NewLogger()
tmpStoreCh := make(chan struct{})
defer close(tmpStoreCh)
logger := log.WithContext(context.Background())
memStore := cache.New(logger, tmpStoreCh)
tok := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{
"s": "abc",
"i": 42,
"f": 1.23,
"b": true,
"t": []float64{1.23, 3.21},
"o": map[string]float64{"a": 0.0, "b": 1.1},
})

key := []byte("mySecretK3y")
token, _ := tok.SignedString(key)

type testCase struct {
name string
req *http.Request
claims map[string]interface{}
wantErrKind string
}

for _, tc := range []testCase{
{
"all ok",
setCookieAndHeader(httptest.NewRequest(http.MethodGet, "/", nil), "Authorization", "Bearer "+token),
map[string]interface{}{"s": "abc", "i": 42, "f": 1.23, "b": true, "t": []float64{1.23, 3.21}, "o": map[string]float64{"a": 0.0, "b": 1.1}},
"",
},
{
"wrong bool",
setCookieAndHeader(httptest.NewRequest(http.MethodGet, "/", nil), "Authorization", "Bearer "+token),
map[string]interface{}{"b": false},
"jwt_token_invalid",
},
{
"wrong int",
setCookieAndHeader(httptest.NewRequest(http.MethodGet, "/", nil), "Authorization", "Bearer "+token),
map[string]interface{}{"i": 0},
"jwt_token_invalid",
},
{
"wrong float",
setCookieAndHeader(httptest.NewRequest(http.MethodGet, "/", nil), "Authorization", "Bearer "+token),
map[string]interface{}{"f": 3.21},
"jwt_token_invalid",
},
{
"wrong string",
setCookieAndHeader(httptest.NewRequest(http.MethodGet, "/", nil), "Authorization", "Bearer "+token),
map[string]interface{}{"s": "asdf"},
"jwt_token_invalid",
},
{
"wrong tuple",
setCookieAndHeader(httptest.NewRequest(http.MethodGet, "/", nil), "Authorization", "Bearer "+token),
map[string]interface{}{"t": []float64{2.34}},
"jwt_token_invalid",
},
{
"wrong object",
setCookieAndHeader(httptest.NewRequest(http.MethodGet, "/", nil), "Authorization", "Bearer "+token),
map[string]interface{}{"o": map[string]float64{"c": 2.2}},
"jwt_token_invalid",
},
{
"missing expected claim",
setCookieAndHeader(httptest.NewRequest(http.MethodGet, "/", nil), "Authorization", "Bearer "+token),
map[string]interface{}{"expected": "str"},
"jwt_token_invalid",
},
} {
t.Run(tc.name, func(subT *testing.T) {
claimValMap := make(map[string]cty.Value)
for k, v := range tc.claims {
switch val := v.(type) {
case string:
claimValMap[k] = cty.StringVal(val)
case int:
claimValMap[k] = cty.NumberIntVal(int64(val))
case float64:
claimValMap[k] = cty.NumberFloatVal(val)
case bool:
claimValMap[k] = cty.BoolVal(val)
case []float64:
var l []cty.Value
for _, e := range val {
l = append(l, cty.NumberFloatVal(e))
}
claimValMap[k] = cty.TupleVal(l)
case map[string]float64:
m := make(map[string]cty.Value)
for mk, mv := range val {
m[mk] = cty.NumberFloatVal(mv)
}
claimValMap[k] = cty.ObjectVal(m)
default:
subT.Fatal("must be one of the mapped types")
}
}
j, err := ac.NewJWT(&config.JWT{
SignatureAlgorithm: "HS256",
Claims: hcl.StaticExpr(cty.ObjectVal(claimValMap), hcl.Range{}),
Bearer: true,
}, key, memStore)
if err != nil {
subT.Error(err)
return
}

tc.req = tc.req.WithContext(context.WithValue(context.Background(), request.LogEntry, log.WithContext(context.Background())))

errKind := ""
err = j.Validate(tc.req)
if err != nil {
cErr := err.(*errors.Error)
errKind = cErr.Kinds()[0]
}
if errKind != tc.wantErrKind {
subT.Errorf("Error want: %s, got: %s", tc.wantErrKind, errKind)
}
})
}
}

func Test_JWT_yields_permissions(t *testing.T) {
log, hook := test.NewLogger()
tmpStoreCh := make(chan struct{})
Expand Down
2 changes: 1 addition & 1 deletion config/definitions.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ type Definitions struct {
JWT []*JWT `hcl:"jwt,block" docs:"Configure a [JWT access control](/configuration/block/jwt) (zero or more)."`
JWTSigningProfile []*JWTSigningProfile `hcl:"jwt_signing_profile,block" docs:"Configure a [JWT signing profile](/configuration/block/jwt_signing_profile) (zero or more)."`
SAML []*SAML `hcl:"saml,block" docs:"Configure a [SAML access control](/configuration/block/saml) (zero or more)."`
OAuth2AC []*OAuth2AC `hcl:"beta_oauth2,block" docs:"Configure an [OAuth2 assess control](/configuration/block/beta_oauth2) (zero or more)."`
OAuth2AC []*OAuth2AC `hcl:"beta_oauth2,block" docs:"Configure an [OAuth2 access control](/configuration/block/beta_oauth2) (zero or more)."`
OIDC []*OIDC `hcl:"oidc,block" docs:"Configure an [OIDC access control](/configuration/block/oidc) (zero or more)."`

// used for documentation
Expand Down
1 change: 1 addition & 0 deletions docs/website/content/2.configuration/0.command-line.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ DEBU[0000] loaded files … […/global.hcl …/conf/a.hcl …/conf/b.hcl …/co
## Network Options

| Argument | Default | Environment Variable | Description |
|:----------------|:--------|:----------------------|:---------------------------------------------|
| `-bind-address` | `"*"` | `COUPER_BIND_ADDRESS` | A comma-separated list of addresses to bind. |

## Oberservation Options
Expand Down
Loading

0 comments on commit 837d989

Please sign in to comment.