Can't limit exposure to certain API endpoints

We’re struggling to limit exposure to a single endpoint for a given service. We do not want all endpoints exposed. However, no matter what we try, ALL endpoints are exposed. Here’s a sample API definition:

{
    "api_definition": {
        "api_id": "my_api",
        "auth": {
            "auth_header_name": "Authorization"
        },
        "info": {
            "name": "my_api",
            "slug": "my_api"
        },
        "CORS": {
            "allowed_headers": [
                "Origin",
                "Accept",
                "Content-Type",
                "X-Requested-With",
                "Authorization"
            ],
            "allowed_methods": [
                "GET",
                "POST",
                "OPTIONS",
                "HEAD"
            ],
            "allowed_origins": [
                "*"
            ],
            "debug": true,
            "enable": true,
            "options_passthrough": false
        },
        "disable_quota": true,
        "do_not_track": false,
        "id": "my_api",
        "name": "my_api",
        "org_id": "default",
        "proxy": {
            "listen_path": "/my_api/",
            "strip_listen_path": true,
            "target_url": "http://my-api.my-api.svc.cluster.local:8888"
        },
        "slug": "my_api",
        "use_keyless": false,
        "version_data": {
            "not_versioned": true,
            "default_version": "",
            "versions": {
                "": {}
            }
        },
        "extended_paths": {
            "white_list": [
                {
                    "path": "^v2/cats",
                    "method_actions": {
                        "POST": {
                            "action": "pass",
                            "code": 200,
                            "data": "",
                            "headers": {}
                        }
                    }
                }
            ]
        }
    }
}

We’re also tried with OAS definitions, and no luck there either.

We’re using Tyk OSS 5.3.0. Other than this, the gateway is working fine.

Any advice would be much appreciated. Thank you!

1 Like

Hello, I’ve upgraded us to tyk-gateway 5.8.0 and we’re having the same problem.

Here’s the new API definition calling /tyk/apis/oas:

{
    "openapi": "3.0.3",
    "info": {
        "title": "my_api",
        "version": "1.0.0"
    },
    "servers": [
        {
            "url": "http://my-api.my-api.svc.cluster.local:8888"
        }
    ],
    "paths": {
        "/v2/places": {
            "post": {
                "summary": "Create a new place",
                "responses": {
                    "200": {
                        "description": "Place created successfully"
                    }
                }
            }
        }
    },
    "x-tyk-api-gateway": {
        "info": {
            "name": "my_api",
            "id": "my_api",
            "state": {
                "active": true
            }
        },
        "server": {
            "listenPath": {
                "value": "/my_api/",
                "strip": true
            },
            "strictRouting": true
        },
        "upstream": {
            "url": "http://distribution-api.distribution-api.svc.cluster.local:8001"
        },
        "security": {
            "authentication": {
                "type": "token",
                "token": {
                    "header": "Authorization"
                }
            }
        },
        "useExtendedPaths": true,
        "extendedPaths": {
            "whiteList": [
                {
                    "path": "^v2/places$",
                    "methodActions": {
                        "POST": {
                            "action": "pass"
                        }
                    }
                }
            ]
        }
    }
}

Ok, I got it working with this configuration:

{
    "openapi": "3.0.3",
    "info": {
        "title": "my_api",
        "version": "1.0.0"
    },
    "servers": [
        {
            "url": "http://my-api.my-api.svc.cluster.local:8888"
        }
    ],
    "paths": {
        "/v2/places": {
            "post": {
                "operationId": "places_post",
                "responses": {
                    "200": {
                        "description": ""
                    }
                }
            }
        }
    },
    "x-tyk-api-gateway": {
        "info": {
            "name": "my-api",
            "id": "my_api",
            "state": {
                "active": true
            }
        },
        "server": {
            "listenPath": {
                "value": "/my-api/",
                "strip": true
            },
            "strictRouting": true
        },
        "upstream": {
            "url": "http://my-api.my-api.svc.cluster.local:8001"
        }
        "middleware": {
            "operations": {
                "places_post": {
                    "allow": {
                        "enabled": true,
                        "ignoreCase": true
                    }
                }
            }
        }
    }
}

Now the next problem is how to set the API key. Now the route I don’t want exposed is correctly returning a 403. However, the public route /my-api/v2/places is giving me this error:

{
    "error": "Access to this API has been disallowed"
}

Now I’m chasing down how the API key should be working.

Hi Skawaguchi,
Based on your middleware configuration

  • It enables an allow middleware for the operation places_post.
  • ‘allow.enabled: true’ means access is granted only if an API key is valid and allowed by the gateway rules.

Basically the config enforces API key authorization. So if you’re hitting the api without a valid key, Tyk will block it with a 403 or “Access disallowed” message, which seems to be what you’re experiencing.
If you want to allow public access to the api without an API key, you will need to explicitly configure that in your Tyk API settings (e.g., disable authentication or add a policy that allows anonymous access). Otherwise, every request must include a valid API key.

For the Public route, You can Add IgnoreAuthentication for the public route. This tells Tyk to skip auth for that route. Be sure to also remove the allow block to avoid conflicts.
For more information you can check Transform Traffic by using Tyk Middlewares.

While For the route you do not want exposed
You can ensure

  • The API uses authentication.type = “standard”
  • You create and pass a valid API key in the Authorization header.
    More information can be found on Managing Classic API Definition

Hope this helps.

Thanks, I ended up figuring it out soon after I posted and forgot to update this thread.

Here’s the configuration that worked:

    "use_keyless": false,
    "auth_configs": {
        "authToken": {
            "name": "authKey",
            "auth_header_name": "Authorization"
        }
    },
1 Like