Cloud endpoints is it possible to protect all API accesses using only a base URL? - google-cloud-endpoints

As in let's say my api is located at domain/_ah/api. We have domain/_ah/api/getUser, domain/_ah/api/stuff/getStuff, domain/_ah/api/stuff/moreStuff/postMoreStuff.
Is it possible to do that by only defining something like this?´
swagger: '2.0'
info:
title: "Cloud Endpoints + Cloud Run"
description: "Sample API on Cloud Endpoints with a Cloud Run backend"
version: "1.0.0"
host: "domain"
schemes:
- "https"
produces:
- "application/json"
x-google-backend:
jwt_audience: "audience"
address: "domain_backend"
protocol: "h2"
paths:
/_ah/api/*:
get, post, put, etc:
description: "Protects Base URL"
operationId: "authInfoFirebase"
security:
- firebase: []
securityDefinitions:
firebase:
authorizationUrl: ""
flow: "implicit"
type: "oauth2"
x-google-issuer: "https://securetoken.google.com/<project_id>"
x-google-jwks_uri: "https://www.googleapis.com/service_accounts/v1/metadata/x509/securetoken#system.gserviceaccount.com"
x-google-audiences: "<project_id>"

I am afraid Cloud Endpoints does not recognize wildcards as you specified.
Quoting the documentation:
“Endpoints only supports URL path template parameters that correspond to entire path segments (delimited by slashes /). URL path template parameters that correspond to partial path segments aren't supported.”[1]
A workaround to wildcards would be to use path templates.
You can use curly braces {} to mark parts of an URL as path parameters, using your example:
domain/_ah/api/{value1}
domain/_ah/api/{value1}/{value2}
domain/_ah/api/{value1}/{value2}/{value3}
Just be careful not to overlap the path templates, like in this example:
/items/{itemid} ---> This is valid
/items/{itemId}/subitem ----> This is valid
/items/cat ----> This is NOT valid
[1] https://cloud.google.com/endpoints/docs/openapi/openapi-limitations#url_path_templating

Related

How to prepend segments to OpenAPI paths?

I created a REST endpoint following this guide: https://quarkus.io/guides/rest-json
Locally I can successfully use swagger UI on <host>/q/swagger-ui which uses <host>/q/openapi as input. So far so good.
However, in production, I use Nginx to forward the requests to <host>/foobar. Thus, the final URLs change to <host>/foobar/q/swagger-ui and <host>/foobar/q/openapi.
nginx.conf snippet where the Quarkus Docker container is running on port 49321:
location /foobar/ {
proxy_pass http://172.17.0.1:49321/;
}
In the application.properties I already added the following line:
quarkus.swagger-ui.urls.direct=/foobar/q/openapi
By doing this, Swagger-UI finds the OpenAPI spec. But the OpenAPI spec contains the wrong URLs because it doesn't know about the /foobar/ URL segment.
How the OpenAPI looks:
---
paths:
/some/url:
get:
tags:
- blabla
responses:
"200":
description: OK
How it needs to look (/foobar/ prepended to path):
---
paths:
/foobar/some/url:
get:
tags:
- blabla
responses:
"200":
description: OK
I already checked available OpenAPI properties on https://quarkus.io/guides/openapi-swaggerui#openapi but they seem to not solve my problem. Any ideas?
I solved it by setting the following in the application.properties:
quarkus.http.root-path=/foobar
and configuring Nginx as follows (nginx.conf):
location /foobar {
proxy_pass http://172.17.0.1:49321/foobar;
}

Encrypting a Secret String in a Prometheus YAML file

I am using OAuth2.0 in this Prometheus YAML file, and don't want to expose the client_secret directly in the file. Does anybody know how to encrypt another file with the client secret (client_secret_file) so that Prometheus can decrypt and use it?
global:
scrape_interval: 15s
evaluation_interval: 15s
alerting:
alertmanagers:
- static_configs:
- targets: []
rule_files: []
scrape_configs:
- job_name: "prometheus"
metrics_path: "/actuator/prometheus"
static_configs:
- targets: ["localhost:8080"]
oauth2:
client_id: ""
client_secret_file: ""
scopes: []
token_url: ""
IIUC, the solution is to use client_secret_file instead of client_secret.
While client_secret includes the secret directly in the Prometheus config, client_secret_file is a file reference to the secret, doesn't disclose the secret to a viewer of the file and the file should not be checked into e.g. source control.
To my knowledge, there's no way to encrypt arbitrary sections of the Prometheus config.

Using x-google-endpoints OpenAPI extension with multiple API versions in Cloud Endpoints

I'm trying to deploy two API versions to Google Cloud Endpoints but end up facing configuration issues during the deployment.
API definition api-1.yaml looks like this:
swagger: "2.0"
info:
description: "API"
title: "API"
version: "1.0.0"
host: "api.endpoints.GCP_PROJECT.cloud.goog"
basePath: "/v1"
x-google-api-name: v1
x-google-endpoints:
- name: "api.endpoints.GCP_PROJECT.cloud.goog"
target: "IP_ADDRESS"
...
This works just fine if deployed alone. However if api-2.yaml is added:
swagger: "2.0"
info:
description: "API"
title: "API"
version: "2.0.0"
host: "api.endpoints.GCP_PROJECT.cloud.goog"
basePath: "/v2"
x-google-api-name: v2
x-google-endpoints:
- name: "api.endpoints.GCP_PROJECT.cloud.goog"
target: "IP_ADDRESS"
...
This leads to deployment error: OpenAPI spec is invalid. Multiple endpoint entries are defined in the extension \'x-google-endpoints\'. At most one entry is allowed.
Removing x-google-endpoints extension from one yaml file works but it leaves another yaml file as incomplete and thus, not optimal solution.
Could there be and issue with combining/validating yaml files during deployment? Can x-google-endpoints extension be used to define .cloud.goog domain for versioned API's?
There are two ways to do this:
1) version is in the domain name, such as v1-api.endpoints.GCP_PROJECT.cloud.goog.
You define and deploy two services; one for v1 and another for v2. Each has its own IP, proper service name and its own backend. This is most straightforward way and easy approach.
2) version is in the path, such as api.endpoints.GCP_PROJECT.cloud.goog/v1. You can only define and deploy one service. But you have two backends. This is tricky one. You can use x-google-backend extension in the OpenApi spec and deploy one Cloud Endpoint service.
You are using two ESP proxy as: v1_esp -> v1, v2_esp -> v2.
Each proxy has its own IP and you are trying to bind a domain name to two IPs. This is not supported.
My suggestion is to use one ESP as such:
esp -> v1 + v2 by using x-google-backend.
With the following:
In the openApi.yaml
paths:
/v1/path1:
...
x-google-backend:
address: v1_host
# do above for all your path/methods
/v2:
...
x-google-backend:
address: v2_host
# do above for all your path/methods
x-google-endpoints:
- name: "api.endpoints.GCP_PROJECT.cloud.goog"
target: "IP_ADDRESS"
add --enable_backend_routing and --rewrite to remove /v1 and /v2 prefix before sending the request to your backends.
We have not tested such deployment, but you can try it.

Unable to access `Google Endpoints API` with firebase auth

Sorry I don't know If I should ask the question here. I used the echo sample project and
deploy it to google cloud endpoints, and I want to configure it with firebase auth instead of api key. the following is the openapi.yaml
paths:
"/echo":
post:
description: "Echo back a given message."
operationId: "echo"
produces:
- "application/json"
responses:
200:
description: "Echo"
schema:
$ref: "#/definitions/echoMessage"
parameters:
- description: "Message to echo"
in: body
name: message
required: true
schema:
$ref: "#/definitions/echoMessage"
security:
- firebase: []
And when I deploy it and access with
curl -d '{"message":"hello world"}' -H "content-
type:application/json""http://[IPADDRESS]:80/echo"
I get the error message.
"message": "Method doesn't allow unregistered callers (callers without
established identity). Please use API Key or other form of API consumer
identity to call this API.",
And if I add the api key.
curl -d '{"message":"hello world"}' -H "content-type:application/json""http://35.194.225.89:80/echo?api_key=[API_KEY]"
I can get the correct result.
I am not sure how to configure the openapi.yaml, please help. thank you very much.

Configuring URI prefix for REST webservice in dropwizard

I am developing a REST API using dropwizard. The resource can be accessed using https://<host>:port/item/1. As it can be seen there is no URI prefix. If I have to configure a URI prefix what needs to be done. Can it be configured in yaml configuration file?
Thanks!
Yes the URI prefix a.k.a root path can be configured in YAML. You could use the simple server factory configuration. It's simple, add these two lines in your YAML. I've used 'api' as the prefix. You can replace it with the URI prefix you want.
server:
rootPath: '/api/*'
A slightly more elaborate server configuration looks something like this,
server:
adminConnectors:
-
port: 18001
type: http
adminContextPath: /admin
applicationConnectors:
-
port: 18000
type: http
rootPath: /api/*
type: default
You can refer to this example https://github.com/dropwizard/dropwizard/blob/master/dropwizard-example/example.yml for server and other configuration details.
It's also a good idea to go through this if you are just getting started with dropwizard http://www.dropwizard.io/0.9.2/docs/getting-started.html

Resources