Skip to content

Conversation

@tkan145
Copy link
Contributor

@tkan145 tkan145 commented Dec 5, 2025

What

THREESCALE-11081

Close #1042

Verification steps

  • Checkout this branch
  • Prepare the cluster
make cluster/prepare/local
  • Install APIM
cat << EOF | oc create -f -
kind: Secret
apiVersion: v1
metadata:
  name: s3-credentials
  namespace: $NAMESPACE
data:
  AWS_ACCESS_KEY_ID: c29tZXRoaW5nCg==
  AWS_BUCKET: c29tZXRoaW5nCg==
  AWS_REGION: dXMtd2VzdC0xCg==
  AWS_SECRET_ACCESS_KEY: c29tZXRoaW5nCg==
type: Opaque
EOF

DOMAIN=$(oc get routes console -n openshift-console -o json | jq -r '.status.ingress[0].routerCanonicalHostname' | sed 's/router-default.//')
cat << EOF | oc create -f -
kind: APIManager
apiVersion: apps.3scale.net/v1alpha1
metadata:
  name: 3scale
  namespace: $NAMESPACE
spec:
  wildcardDomain: $DOMAIN
  apicast:
    stagingSpec:
      replicas: 0
    productionSpec:
      replicas: 0
  system:
    fileStorage:
      simpleStorageService:
        configurationSecretRef:
          name: s3-credentials
  externalComponents:
    backend:
      redis: true
    system:
      database: true
      redis: true
EOF
  • Start the operator
make run
  • Wait for the installation to finish
  • Setup product/backend
# Get the ADMIN_URL and ADMIN_ACCESS_TOKEN from apimanager and system-seed secret
DOMAIN=$(oc get routes console -n openshift-console -o json | jq -r '.status.ingress[0].routerCanonicalHostname' | sed 's/router-default.//')
ADMIN_ACCESS_TOKEN=$(oc get secret system-seed -n 3scale-test -o jsonpath="{.data.ADMIN_ACCESS_TOKEN}"| base64 --decode)
oc project 3scale-test
# Create the required secrets for Accounts, products and backends. 
oc apply -f - <<EOF
---
apiVersion: v1
kind: Secret
metadata:
  name: mytenant
type: Opaque
stringData:
  adminURL: https://3scale-admin.$DOMAIN
  token: $ADMIN_ACCESS_TOKEN
EOF
# user secret
oc apply -f - <<EOF
---
apiVersion: v1
kind: Secret
metadata:
  name: myusername01
stringData:
  password: "123456"
EOF
# Developer User
oc apply -f - <<EOF
---
apiVersion: capabilities.3scale.net/v1beta1
kind: DeveloperUser
metadata:
  name: developeruser01
  namespace: 3scale-test
  annotations:
    "insecure_skip_verify": "true"
spec:
  developerAccountRef:
    name: developeraccount01
  email: [email protected]
  passwordCredentialsRef:
    name: myusername01
  providerAccountRef:
    name: mytenant
  role: admin
  username: myusername01
EOF
sleep 30
# TODO check for developer user completed
oc apply -f - <<EOF
---
apiVersion: capabilities.3scale.net/v1beta1
kind: DeveloperAccount
metadata:
  name: developeraccount01
  namespace: 3scale-test
  annotations:
    "insecure_skip_verify": "true"
spec:
  orgName: 3scale-test
  providerAccountRef:
    name: mytenant
EOF
# deploy httpbin and use it as the backend
oc new-project httpbin
oc new-app quay.io/trepel/httpbin
oc get svc
oc scale deployment/httpbin --namespace httpbin --replicas=8 
oc project 3scale-test

# create backend
oc apply -f - <<EOF
---
apiVersion: capabilities.3scale.net/v1beta1
kind: Backend
metadata:
  name: backend1-cr
  namespace: 3scale-test
  annotations:
    "insecure_skip_verify": "true"
spec:
  mappingRules:
    - httpMethod: GET
      increment: 1
      last: true
      metricMethodRef: GET_one
      pattern: /
    - httpMethod: POST
      increment: 1
      metricMethodRef: hits
      pattern: /
  methods:
    GET_one:
      description: Number of API hits
      friendlyName: GET_one
  metrics:
    hits:
      description: Number of API hits
      friendlyName: Hits
      unit: hits
  name: backend1
  privateBaseURL: 'http://httpbin.httpbin.svc:8080'
  systemName: backend1
EOF
# Product
oc apply -f - <<EOF
---
apiVersion: capabilities.3scale.net/v1beta1
kind: Product
metadata:
  name: product1-cr
  namespace: 3scale-test
  annotations:
    "insecure_skip_verify": "true"
spec:
  applicationPlans:
    plan01:
      name: "My Plan 01"
    plan02:
      name: "My Plan 02"
  deployment:
    apicastHosted:
      authentication:
        userkey:
          authUserKey: token
  name: product1
  backendUsages:
    backend1:
      path: /
  mappingRules:
    - httpMethod: GET
      pattern : "/"
      metricMethodRef: hits
      increment: 1
    - httpMethod: POST
      pattern : "/"
      metricMethodRef: hits
      increment: 1    
EOF
oc apply -f - <<EOF
---
apiVersion: capabilities.3scale.net/v1beta1
kind: Product
metadata:
  name: product2-cr
  namespace: 3scale-test
  annotations:
    "insecure_skip_verify": "true"
spec:
  applicationPlans:
    plan01:
      name: "My Plan 01"
    plan02:
      name: "My Plan 02"
  deployment:
    apicastHosted:
      authentication:
        appKeyAppID:
          appID: token
  name: product2
  backendUsages:
    backend1:
      path: /
  mappingRules:
    - httpMethod: GET
      pattern : "/"
      metricMethodRef: hits
      increment: 1
    - httpMethod: POST
      pattern : "/"
      metricMethodRef: hits
      increment: 1    
EOF
# application
oc apply -f - <<EOF
---
apiVersion: capabilities.3scale.net/v1beta1
kind: Application
metadata:
  name: application-cr
  namespace: 3scale-test
  annotations:
    "insecure_skip_verify": "true"
spec:
  accountCR: 
    name: developeraccount01
  applicationPlanName: plan01
  productCR: 
    name: product1-cr
  name: testApp
  description: further testing
EOF

# TODO proxy promote
oc apply -f - <<EOF
---
apiVersion: capabilities.3scale.net/v1beta1
kind: ProxyConfigPromote
metadata:
  name: product1-v1-production
  namespace: 3scale-test
  annotations:
    "insecure_skip_verify": "true"
spec:
  productCRName: product1-cr
  production: true
  deleteCR: true
EOF

sleep 30
echo Product Route: 
echo "https://$(oc get routes | grep product1 |grep production| awk '{print $2}')" 
echo
echo User_key: 
echo $(curl -s -X 'GET' "https://3scale-admin.$DOMAIN/admin/api/applications.xml?access_token=$ADMIN_ACCESS_TOKEN&page=1&per_page=500&service_id=3" -H 'accept: */*' | grep -oP '<user_key>\K[^<]+' | sed 's/\s//g')
  • Wait for the script to finish and login into the admin portal and confirm that a product is setup with an application called testApp
  • Setup secret
cat << EOF | oc create -f -
kind: Secret
apiVersion: v1
metadata:
  name: auth-secret
  namespace: 3scale-test
data:
  ApplicationID: 'Zm9vCg=='
  ApplicationKey: 'Zm9vCg=='
  UserKey: >-
    dGVzdGtleQo=
type: Opaque
EOF
  • Setup Application with user_key
oc apply -f - <<EOF
---
apiVersion: capabilities.3scale.net/v1beta1
kind: Application
metadata:
  name: application-cr2
  namespace: 3scale-test
  annotations:
    "insecure_skip_verify": "true"
spec:
  accountCR: 
    name: developeraccount01
  applicationPlanName: plan01
  authSecretRef:
    name: auth-secret
  productCR: 
    name: product1-cr
  name: testApp2
  description: further testing
EOF
  • Check in Admin portal, you should see a new testApp2 application under product1 with UserKey set to testkey
  • Setup Application with app_id/app_key
oc apply -f - <<EOF
---
apiVersion: capabilities.3scale.net/v1beta1
kind: Application
metadata:
  name: application-cr3
  namespace: 3scale-test
  annotations:
    "insecure_skip_verify": "true"
spec:
  accountCR: 
    name: developeraccount01
  applicationPlanName: plan01
  authSecretRef:
    name: auth-secret
  productCR: 
    name: product2-cr
  name: testApp3
  description: further testing
EOF
  • Check in Admin portal, you should see a new testApp3 application with product2 with Application ID/Application Key set to something

@tkan145 tkan145 requested a review from a team as a code owner December 5, 2025 01:21
@briangallagher
Copy link
Contributor

briangallagher commented Dec 5, 2025

Snyk checks have passed. No issues have been found so far.

Status Scanner Critical High Medium Low Total (0)
Open Source Security 0 0 0 0 0 issues
Licenses 0 0 0 0 0 issues

💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse.

@tkan145
Copy link
Contributor Author

tkan145 commented Dec 5, 2025

@dcheng1248 would you able to give this PR a quick look and let me know if it meets your requirements?


func validateSecretForAuthModeAppIDAppKey(s *corev1.Secret) error {
if _, ok := s.Data[CredentialSecretKeyNameAppID]; !ok {
return fmt.Errorf("secret %s used as user-key authentication mode, but lacks %s key",

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the error message should say appid/appkey as authentication mode (not user-key), and the lacking key should be appid/appkey instead of userkey. Same issue for OIDC validation.

@dcheng1248
Copy link

@tkan145 I cannot test the operator directly on our cluster, but based on the code it would indeed solve our issue, thanks for the work!
I left a comment on where I think might be a typo.

@tkan145 tkan145 changed the title THREESCALE-11081 The ability to set the applicaiton_id & application_key in the application CRD creation THREESCALE-11081 The ability to set the application_id & application_key in the application CRD creation Dec 8, 2025
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.

Allow Application CR to configure custom application_id

3 participants