• Stars
    star
    536
  • Rank 82,794 (Top 2 %)
  • Language
    Java
  • License
    Apache License 2.0
  • Created almost 7 years ago
  • Updated 4 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Adds a Metrics Endpoint to Keycloak

License

Keycloak Metrics SPI

A Service Provider that adds a metrics endpoint to Keycloak. The endpoint returns metrics data ready to be scraped by Prometheus.

Two distinct providers are defined:

  • MetricsEventListener to record the internal Keycloak events
  • MetricsEndpoint to expose the data through a custom endpoint

The endpoint is available under <base url>/realms/<realm>/metrics (Quarkus) or <base url>/auth/realms/<realm>/metrics (Wildfly). It will return data for all realms, no matter which realm you use in the URL.

License

See LICENSE file

Running the tests

$ ./gradlew test

Build

There are two ways to build the project using:

You can choose between the tools the most convenient for you. Read further how to use each of them.

Gradle

The project is packaged as a jar file and bundles the prometheus client libraries.

$ ./gradlew jar

builds the jar and writes it to build/libs.

Maven

To build the jar file using maven run the following command (will bundle the prometheus client libraries as well):

mvn package

It will build the project and write jar to the ./target.

Configurable versions for some packages

You can build the project using a different version of Keycloak or Prometheus, running the command:

For Gradle

$ ./gradlew -PkeycloakVersion="15.0.2.Final" -PprometheusVersion="0.12.0" jar

or by changing the gradle.properties file in the root of the project.

For Maven

mvn clean package -Dkeycloak.version=15.0.0 -Dprometheus.version=0.9.0

Install and setup

On Keycloak Widfly Distribution

This section assumes /opt/jboss as the Keycloak home directory, which is used on the jboss/keycloak reference container on Docker Hub.

  • Drop the jar into the /opt/jboss/keycloak/standalone/deployments/ subdirectory of your Keycloak installation.

  • Touch a dodeploy file into the /opt/jboss/keycloak/standalone/deployments/ subdirectory of your Keycloak installation.

# If your jar file is `keycloak-metrics-spi-2.0.2.jar`
cd /opt/jboss/keycloak/standalone/deployments/
touch keycloak-metrics-spi-2.0.2.jar.dodeploy
  • Restart the keycloak service.

On Keycloak Quarkus Distribution

We assume the home of keycloak is on the default /opt/keycloak

You will need to either copy the jar into the build step and run step, or copy it from the build stage. Following the example docker instructions No need to add .dodeploy.

# On build stage
COPY keycloak-metrics-spi.jar /opt/keycloak/providers/

# On run stage
COPY keycloak-metrics-spi.jar /opt/keycloak/providers/

If not copied to both stages keycloak will complain

ERROR: Failed to start quarkus
ERROR: Failed to open /opt/keycloak/lib/../providers/keycloak-metrics-spi.jar

The endpoint for the metrics is <url>/<http_relative_path>/realms/<realm>/metrics

Enable metrics-listener event

  • To enable the event listener via the GUI interface, go to Manage -> Events -> Config. The Event Listeners configuration should have an entry named metrics-listener.

  • To enable the event listener via the Keycloak CLI, such as when building a Docker container, use these commands.

$ /opt/jboss/keycloak/bin/kcadm.sh config credentials --server http://localhost:8080/auth --realm master --user $KEYCLOAK_USER --password $KEYCLOAK_PASSWORD
$ /opt/jboss/keycloak/bin/kcadm.sh update events/config -s "eventsEnabled=true" -s "adminEventsEnabled=true" -s "eventsListeners+=metrics-listener"
$ usr/bin/rm -f /opt/jboss/.keycloak/kcadm.config

PushGateway

If you are running keycloak in a cluster or if you are running behind a load balancer, you might have problems scraping the metrics endpoint of each node. To fix this, you can push your metrics to a PushGateway.

Prometheus PushGateway

You can enable pushing to PushGateway by setting the environment variable PROMETHEUS_PUSHGATEWAY_ADDRESS in the keycloak instance. The format is host:port or ip:port of the Pushgateway.

Grouping instances

The default value for the grouping key "instance" is the IP. This can be changed setting the environment variable PROMETHEUS_GROUPING_KEY_INSTANCE to a fixed value. Additionaly, if the value provided starts with the prefix ENVVALUE:, the string after the : will be used to get the value from the environment variable with that name. For example, with the next setting:

PROMETHEUS_GROUPING_KEY_INSTANCE=ENVVALUE:HOSTNAME

instance will have the value of the environment variable HOSTNAME

Grouping instances by cluster

if you have multiple KeyCloak clusters on the same runtime then you might like to groups instances by cluster's name.

That's the purpose of the environment variable PROMETHEUS_PUSHGATEWAY_JOB. The default job value is keycloak for all the instances.

For example for all the instances of a KeyCloak cluster #1 you can set:

PROMETHEUS_PUSHGATEWAY_JOB="keycloak-cluster1"

Metrics

For each metric, the endpoint returns 2 or more lines of information:

  • # HELP: A small description provided by the SPI.
  • # TYPE: The type of metric, namely counter and gauge. More info about types at prometheus.io/docs.
  • Provided there were any values, the last one recorded. If no value has been recorded yet, no more lines will be given.
  • In case the same metric have different labels, there is a different line for each one. By default all metrics are labeled by realm. More info about labels at prometheus.io/docs.

Example:

# HELP jvm_memory_bytes_committed Committed (bytes) of a given JVM memory area.
# TYPE jvm_memory_bytes_committed gauge
jvm_memory_bytes_committed{area="heap",} 2.00802304E8
jvm_memory_bytes_committed{area="nonheap",} 2.0217856E8

JVM performance

A variety of JVM metrics are provided

Generic events

Every single internal Keycloak event is being shared through the endpoint, with the descriptions Generic Keycloak User event or Generic Keycloak Admin event. Most of these events are not likely useful for the majority users but are provided for good measure. A complete list of the events can be found at Keycloak documentation.

Featured events

There are however a few events that are particularly more useful from a mobile app perspective. These events have been overriden by the SPI and are described more thoroughly below.

keycloak_login_attempts

This counter counts every login attempt performed by a non-admin user. It also distinguishes logins by the utilised identity provider by means of the label provider and by client with the label client_id..

# HELP keycloak_login_attempts Total number of login attempts
# TYPE keycloak_login_attempts counter
keycloak_login_attempts{realm="test",provider="keycloak",client_id="account"} 3.0
keycloak_login_attempts{realm="test",provider="github",client_id="application1"} 2.0
keycloak_logins

This counter counts every login performed by a non-admin user. It also distinguishes logins by the utilised identity provider by means of the label provider and by client with the label client_id..

# HELP keycloak_logins Total successful logins
# TYPE keycloak_logins counter
keycloak_logins{realm="test",provider="keycloak",client_id="account"} 3.0
keycloak_logins{realm="test",provider="github",client_id="application1"} 2.0
keycloak_failed_login_attempts

This counter counts every login performed by a non-admin user that fails, being the error described by the label error. It also distinguishes logins by the identity provider used by means of the label provider and by client with the label client_id.

# HELP keycloak_failed_login_attempts Total failed login attempts
# TYPE keycloak_failed_login_attempts counter
keycloak_failed_login_attempts{realm="test",provider="keycloak",error="invalid_user_credentials",client_id="application1"} 6.0
keycloak_failed_login_attempts{realm="test",provider="keycloak",error="user_not_found",client_id="application1"} 2.0
keycloak_client_logins

This counter counts every client login.

# HELP keycloak_client_logins Total successful client logins
# TYPE keycloak_client_logins counter
keycloak_client_logins{realm="test",provider="keycloak",client_id="account"} 4.0
keycloak_client_logins{realm="test",provider="github",client_id="application2"} 7.0
keycloak_failed_client_login_attempts

This counter counts every client login performed that fails, being the error described by the label error.

# HELP keycloak_failed_client_login_attempts Total failed client login attempts
# TYPE keycloak_failed_client_login_attempts counter
keycloak_failed_client_login_attempts{realm="test2",provider="keycloak",error="invalid_client_credentials",client_id="application2"} 5.0
keycloak_failed_client_login_attempts{realm="test2",provider="keycloak",error="client_not_found",client_id="application2"} 3.0
keycloak_refresh_tokens

This counter counts every refresh token.

# HELP keycloak_refresh_tokens Total number of successful token refreshes
# TYPE keycloak_refresh_tokens counter
keycloak_refresh_tokens{realm="test3",provider="keycloak",client_id="account"} 1.0
keycloak_refresh_tokens{realm="test3",provider="github",client_id="application3"} 2.0
keycloak_refresh_tokens_errors

This counter counts every refresh token that fails.

# HELP keycloak_refresh_tokens_errors Total number of failed token refreshes
# TYPE keycloak_refresh_tokens_errors counter
keycloak_refresh_tokens_errors{realm="test3",provider="keycloak",error="invalid_token",client_id="application3"} 3.0
keycloak_registrations

This counter counts every new user registration. It also distinguishes registrations by the identity provider used by means of the label provider and by client with the label client_id..

# HELP keycloak_registrations Total registered users
# TYPE keycloak_registrations counter
keycloak_registrations{realm="test",provider="keycloak",client_id="application1"} 1.0
keycloak_registrations{realm="test",provider="github",client_id="application1"} 1.0
keycloak_registrations_errors

This counter counts every new user registration that fails, being the error described by the label error. It also distinguishes registrations by the identity provider used by means of the label provider and by client with the label client_id..

# HELP keycloak_registrations_errors Total errors on registrations
# TYPE keycloak_registrations_errors counter
keycloak_registrations_errors{realm="test",provider="keycloak",error="invalid_registration",client_id="application1",} 2.0
keycloak_registrations_errors{realm="test",provider="keycloak",error="email_in_use",client_id="application1",} 3.0
keycloak_code_to_tokens

This counter counts every code to token.

# HELP keycloak_code_to_tokens Total number of successful code to token
# TYPE keycloak_code_to_tokens counter
keycloak_code_to_tokens{realm="test4",provider="keycloak",client_id="account"} 3.0
keycloak_code_to_tokens{realm="test4",provider="github",client_id="application4"} 1.0
keycloak_code_to_tokens_errors

This counter counts every code to token performed that fails, being the error described by the label error.

# HELP keycloak_code_to_tokens_errors Total number of failed code to token
# TYPE keycloak_code_to_tokens_errors counter
keycloak_code_to_tokens_errors{realm="test4",provider="keycloak",error="invalid_client_credentials",client_id="application4"} 7.0
keycloak_request_duration

This histogram records the response times per http method and puts them in one of nine buckets:

  • Requests that take 50ms or less
  • Requests that take 100ms or less
  • Requests that take 250ms or less
  • Requests that take 500ms or less
  • Requests that take 1s or less
  • Requests that take 2s or less
  • Requests that take 10s or less
  • Requests that take 30s or less
  • Any request that takes longer than 30s

The response from this type of metrics has the following format:

# HELP keycloak_request_duration Request duration
# TYPE keycloak_request_duration histogram
keycloak_request_duration_bucket{method="PUT",le="50.0",} 0.0
keycloak_request_duration_bucket{method="PUT",le="100.0",} 0.0
keycloak_request_duration_bucket{method="PUT",le="250.0",} 0.0
keycloak_request_duration_bucket{method="PUT",le="500.0",} 0.0
keycloak_request_duration_bucket{method="PUT",le="1000.0",} 1.0
keycloak_request_duration_bucket{method="PUT",le="2000.0",} 2.0
keycloak_request_duration_bucket{method="PUT",le="10000.0",} 2.0
keycloak_request_duration_bucket{method="PUT",le="30000.0",} 2.0
keycloak_request_duration_bucket{method="PUT",le="+Inf",} 2.0
keycloak_request_duration_count{method="PUT",} 2.0
keycloak_request_duration_sum{method="PUT",} 3083.0

This tells you that there have been zero requests that took less than 500ms. There was one request that took less than 1s. All the other requests took less than 2s.

Aside from the buckets there are also the sum and count metrics for every method. In the above example they tell you that there have been two requests total for this http method. The sum of all response times for this combination is 3083ms.

To get the average request duration over the last five minutes for the whole server you can use the following Prometheus query:

rate(keycloak_request_duration_sum[5m]) / rate(keycloak_request_duration_count[5m])
keycloak_response_errors

This counter counts the number of response errors (responses where the http status code is in the 400 or 500 range).

# HELP keycloak_response_errors Total number of error responses
# TYPE keycloak_response_errors counter
keycloak_response_errors{code="500",method="GET",} 1

Metrics URI

The URI can be added to the metrics by setting the environment variable URI_METRICS_ENABLED to true. This will output a consolidated realm URI value to the metrics. The realm value is replaced with a generic {realm} value

# HELP keycloak_request_duration Request duration
# TYPE keycloak_request_duration histogram
keycloak_request_duration_bucket{code="200",method="GET",resource="realms,realms/master/protocol/openid-connect",uri="realms/{realm}/protocol/openid-connect/3p-cookies/step2.html",le="50.0",} 2.0
keycloak_request_duration_bucket{code="200",method="GET",resource="realms,realms/master/protocol/openid-connect",uri="realms/{realm}/protocol/openid-connect/3p-cookies/step2.html",le="100.0",} 2.0
keycloak_request_duration_bucket{code="200",method="GET",resource="realms,realms/master/protocol/openid-connect",uri="realms/{realm}/protocol/openid-connect/3p-cookies/step2.html",le="250.0",} 2.0
keycloak_request_duration_bucket{code="200",method="GET",resource="realms,realms/master/protocol/openid-connect",uri="realms/{realm}/protocol/openid-connect/3p-cookies/step2.html",le="500.0",} 2.0
keycloak_request_duration_bucket{code="200",method="GET",resource="realms,realms/master/protocol/openid-connect",uri="realms/{realm}/protocol/openid-connect/3p-cookies/step2.html",le="1000.0",} 2.0
keycloak_request_duration_bucket{code="200",method="GET",resource="realms,realms/master/protocol/openid-connect",uri="realms/{realm}/protocol/openid-connect/3p-cookies/step2.html",le="2000.0",} 2.0
keycloak_request_duration_bucket{code="200",method="GET",resource="realms,realms/master/protocol/openid-connect",uri="realms/{realm}/protocol/openid-connect/3p-cookies/step2.html",le="10000.0",} 2.0
keycloak_request_duration_bucket{code="200",method="GET",resource="realms,realms/master/protocol/openid-connect",uri="realms/{realm}/protocol/openid-connect/3p-cookies/step2.html",le="30000.0",} 2.0
keycloak_request_duration_bucket{code="200",method="GET",resource="realms,realms/master/protocol/openid-connect",uri="realms/{realm}/protocol/openid-connect/3p-cookies/step2.html",le="+Inf",} 2.0
keycloak_request_duration_bucket{code="200",method="GET",resource="admin,admin/master/console",uri="admin/{realm}/console/whoami",le="50.0",} 0.0
keycloak_request_duration_bucket{code="200",method="GET",resource="admin,admin/master/console",uri="admin/{realm}/console/whoami",le="100.0",} 0.0
keycloak_request_duration_bucket{code="200",method="GET",resource="admin,admin/master/console",uri="admin/{realm}/console/whoami",le="250.0",} 1.0
keycloak_request_duration_bucket{code="200",method="GET",resource="admin,admin/master/console",uri="admin/{realm}/console/whoami",le="500.0",} 1.0
keycloak_request_duration_bucket{code="200",method="GET",resource="admin,admin/master/console",uri="admin/{realm}/console/whoami",le="1000.0",} 1.0
keycloak_request_duration_bucket{code="200",method="GET",resource="admin,admin/master/console",uri="admin/{realm}/console/whoami",le="2000.0",} 1.0
keycloak_request_duration_bucket{code="200",method="GET",resource="admin,admin/master/console",uri="admin/{realm}/console/whoami",le="10000.0",} 1.0
keycloak_request_duration_bucket{code="200",method="GET",resource="admin,admin/master/console",uri="admin/{realm}/console/whoami",le="30000.0",} 1.0
keycloak_request_duration_bucket{code="200",method="GET",resource="admin,admin/master/console",uri="admin/{realm}/console/whoami",le="+Inf",} 1.0

If the quanitiy of metrics is too high they can also be filtered to specific values using the URI_METRICS_FILTER e.g token,clients. This is a comman delimited value of keywords to search and display the required URIs.

# HELP keycloak_request_duration Request duration
# TYPE keycloak_request_duration histogram
keycloak_request_duration_bucket{code="200",method="POST",resource="realms,realms/master/protocol/openid-connect",uri="realms/{realm}/protocol/openid-connect/token",le="50.0",} 0.0
keycloak_request_duration_bucket{code="200",method="POST",resource="realms,realms/master/protocol/openid-connect",uri="realms/{realm}/protocol/openid-connect/token",le="100.0",} 1.0
keycloak_request_duration_bucket{code="200",method="POST",resource="realms,realms/master/protocol/openid-connect",uri="realms/{realm}/protocol/openid-connect/token",le="250.0",} 1.0
keycloak_request_duration_bucket{code="200",method="POST",resource="realms,realms/master/protocol/openid-connect",uri="realms/{realm}/protocol/openid-connect/token",le="500.0",} 1.0
keycloak_request_duration_bucket{code="200",method="POST",resource="realms,realms/master/protocol/openid-connect",uri="realms/{realm}/protocol/openid-connect/token",le="1000.0",} 1.0
keycloak_request_duration_bucket{code="200",method="POST",resource="realms,realms/master/protocol/openid-connect",uri="realms/{realm}/protocol/openid-connect/token",le="2000.0",} 1.0
keycloak_request_duration_bucket{code="200",method="POST",resource="realms,realms/master/protocol/openid-connect",uri="realms/{realm}/protocol/openid-connect/token",le="10000.0",} 1.0
keycloak_request_duration_bucket{code="200",method="POST",resource="realms,realms/master/protocol/openid-connect",uri="realms/{realm}/protocol/openid-connect/token",le="30000.0",} 1.0
keycloak_request_duration_bucket{code="200",method="POST",resource="realms,realms/master/protocol/openid-connect",uri="realms/{realm}/protocol/openid-connect/token",le="+Inf",} 1.0
keycloak_request_duration_bucket{code="200",method="GET",resource="admin,admin/master/console",uri="",le="50.0",} 4.0
keycloak_request_duration_bucket{code="200",method="GET",resource="admin,admin/master/console",uri="",le="100.0",} 5.0
keycloak_request_duration_bucket{code="200",method="GET",resource="admin,admin/master/console",uri="",le="250.0",} 6.0
keycloak_request_duration_bucket{code="200",method="GET",resource="admin,admin/master/console",uri="",le="500.0",} 6.0
keycloak_request_duration_bucket{code="200",method="GET",resource="admin,admin/master/console",uri="",le="1000.0",} 6.0
keycloak_request_duration_bucket{code="200",method="GET",resource="admin,admin/master/console",uri="",le="2000.0",} 6.0
keycloak_request_duration_bucket{code="200",method="GET",resource="admin,admin/master/console",uri="",le="10000.0",} 6.0
keycloak_request_duration_bucket{code="200",method="GET",resource="admin,admin/master/console",uri="",le="30000.0",} 6.0
keycloak_request_duration_bucket{code="200",method="GET",resource="admin,admin/master/console",uri="",le="+Inf",} 6.0
keycloak_request_duration_count{code="200",method="GET",resource="admin,admin/master/console",uri="",} 6.0
keycloak_request_duration_sum{code="200",method="GET",resource="admin,admin/master/console",uri="",} 274.0
keycloak_request_duration_bucket{code="200",method="GET",resource="admin,admin/serverinfo",uri="",le="50.0",} 1.0
keycloak_request_duration_bucket{code="200",method="GET",resource="admin,admin/serverinfo",uri="",le="100.0",} 1.0
keycloak_request_duration_bucket{code="200",method="GET",resource="admin,admin/serverinfo",uri="",le="250.0",} 1.0
keycloak_request_duration_bucket{code="200",method="GET",resource="admin,admin/serverinfo",uri="",le="500.0",} 1.0
keycloak_request_duration_bucket{code="200",method="GET",resource="admin,admin/serverinfo",uri="",le="1000.0",} 1.0
keycloak_request_duration_bucket{code="200",method="GET",resource="admin,admin/serverinfo",uri="",le="2000.0",} 1.0
keycloak_request_duration_bucket{code="200",method="GET",resource="admin,admin/serverinfo",uri="",le="10000.0",} 1.0
keycloak_request_duration_bucket{code="200",method="GET",resource="admin,admin/serverinfo",uri="",le="30000.0",} 1.0
keycloak_request_duration_bucket{code="200",method="GET",resource="admin,admin/serverinfo",uri="",le="+Inf",} 1.0
keycloak_request_duration_count{code="200",method="GET",resource="admin,admin/serverinfo",uri="",} 1.0

To remove the consolidated realm URI, set URI_METRICS_DETAILED to true

# HELP keycloak_request_duration Request duration
# TYPE keycloak_request_duration histogram
keycloak_request_duration_bucket{code="200",method="POST",resource="realms,realms/master/protocol/openid-connect",uri="realms/master/protocol/openid-connect/token",le="50.0",} 0.0
keycloak_request_duration_bucket{code="200",method="POST",resource="realms,realms/master/protocol/openid-connect",uri="realms/master/protocol/openid-connect/token",le="100.0",} 0.0
keycloak_request_duration_bucket{code="200",method="POST",resource="realms,realms/master/protocol/openid-connect",uri="realms/master/protocol/openid-connect/token",le="250.0",} 1.0
keycloak_request_duration_bucket{code="200",method="POST",resource="realms,realms/master/protocol/openid-connect",uri="realms/master/protocol/openid-connect/token",le="500.0",} 1.0
keycloak_request_duration_bucket{code="200",method="POST",resource="realms,realms/master/protocol/openid-connect",uri="realms/master/protocol/openid-connect/token",le="1000.0",} 1.0
keycloak_request_duration_bucket{code="200",method="POST",resource="realms,realms/master/protocol/openid-connect",uri="realms/master/protocol/openid-connect/token",le="2000.0",} 1.0
keycloak_request_duration_bucket{code="200",method="POST",resource="realms,realms/master/protocol/openid-connect",uri="realms/master/protocol/openid-connect/token",le="10000.0",} 1.0
keycloak_request_duration_bucket{code="200",method="POST",resource="realms,realms/master/protocol/openid-connect",uri="realms/master/protocol/openid-connect/token",le="30000.0",} 1.0
keycloak_request_duration_bucket{code="200",method="POST",resource="realms,realms/master/protocol/openid-connect",uri="realms/master/protocol/openid-connect/token",le="+Inf",} 1.0
keycloak_request_duration_bucket{code="200",method="GET",resource="admin,admin/serverinfo",uri="",le="50.0",} 1.0
keycloak_request_duration_bucket{code="200",method="GET",resource="admin,admin/serverinfo",uri="",le="100.0",} 1.0
keycloak_request_duration_bucket{code="200",method="GET",resource="admin,admin/serverinfo",uri="",le="250.0",} 1.0
keycloak_request_duration_bucket{code="200",method="GET",resource="admin,admin/serverinfo",uri="",le="500.0",} 1.0
keycloak_request_duration_bucket{code="200",method="GET",resource="admin,admin/serverinfo",uri="",le="1000.0",} 1.0
keycloak_request_duration_bucket{code="200",method="GET",resource="admin,admin/serverinfo",uri="",le="2000.0",} 1.0
keycloak_request_duration_bucket{code="200",method="GET",resource="admin,admin/serverinfo",uri="",le="10000.0",} 1.0
keycloak_request_duration_bucket{code="200",method="GET",resource="admin,admin/serverinfo",uri="",le="30000.0",} 1.0
keycloak_request_duration_bucket{code="200",method="GET",resource="admin,admin/serverinfo",uri="",le="+Inf",} 1.0
keycloak_request_duration_count{code="200",method="GET",resource="admin,admin/serverinfo",uri="",} 1.0
keycloak_request_duration_sum{code="200",method="GET",resource="admin,admin/serverinfo",uri="",} 19.0

External Access

To disable metrics being externally accessible to a cluster. Set the environment variable 'DISABLE_EXTERNAL_ACCESS'. Once set enable the header 'X-Forwarded-Host' on your proxy. This is enabled by default on HA Proxy on Openshift.

Grafana Dashboard

You can use this dashboard or create yours https://grafana.com/grafana/dashboards/10441-keycloak-metrics-dashboard/

More Repositories

1

offix

GraphQL Offline Client and Server
TypeScript
759
star
2

aerogear-unifiedpush-server

🚀 AeroGear UnifiedPush Server
Java
457
star
3

create-graphql

Command-line utility to build production-ready servers with GraphQL.
JavaScript
440
star
4

graphback

Graphback - Out of the box GraphQL server and client
TypeScript
409
star
5

aerogear-ios-oauth2

Client library for OAuth2/OpenID Connect
Swift
163
star
6

keycloak-connect-graphql

Add Keyloak Authentication and Authorization to your GraphQL server.
TypeScript
155
star
7

charmil

The framework for building modular plugin based CLI's using Cobra and Golang
Go
116
star
8

datasync-voyager

🚀 Complete GraphQL Node.js Server ready for production
TypeScript
51
star
9

OpenVolunteerPlatform

Platform for building volunteer management systems dedicated for local gov and charity organizations
TypeScript
51
star
10

aerogear-ios-http

Lightweight lib around NSURLSession to ease HTTP calls
Swift
45
star
11

aerogear-android-cookbook

Java
41
star
12

graphql-link

graphql-link is a GraphQL server that composes other GraphQL or OpenAPI endpoints
CSS
38
star
13

offix-android

Apollo GraphQL offline extensions for Android Platform
Kotlin
37
star
14

aerogear-cordova-push

✨ Cordova plugin to support AeroGear UnifiedPush notifications ✨
JavaScript
34
star
15

datasync-starter

GraphQL Low Code React and Node.js DataSync Application template
TypeScript
32
star
16

graphql-query-mapper

Query your GraphQL data efficiently
TypeScript
30
star
17

aerogear-ios-push

AeroGear UnifiedPush Client Registration SDK (Swift)
Swift
29
star
18

graphql-metadata

Annotate your graphql schema with lightweight directives
TypeScript
28
star
19

aerogear-ios-cookbook

Swift
23
star
20

android-showcase-template

Showcase template app for the AeroGear Android SDK
Java
21
star
21

graphql-testx

A GraphQL server for testing GraphQL applications or libraries based on Graphback
TypeScript
15
star
22

aerogear-android-push

Push provides support for integrating with push. Currently only using Firebase Cloud Messaging (FCM) with the AeroGear UnifiedPush Server (UPS)
Java
15
star
23

uniforms-patternfly

Uniforms patternfly
TypeScript
13
star
24

push-network-proxies

Simple mock/proxy servers for FCM and APNs
Java
13
star
25

aerogear.org

Jekyll based project site repo for aerogear.org
HTML
12
star
26

aerogear-unifiedpush-nodejs-client

Node.js API to access the Unified Push Server
JavaScript
12
star
27

aerogear-digger

Digger on Jenkins: An OpenSource Build Farm for mobile app builds in the cloud
Ruby
10
star
28

mobile-developer-console

Mobile Developer Console
CSS
9
star
29

aerogear-js-sdk

AeroGear Mobile SDK
TypeScript
9
star
30

mobile-security-service-operator

Go
9
star
31

mobile-docs

Documentation for setting up and using Mobile Services on OpenShift
JavaScript
8
star
32

aerogear-android-sdk

AeroGear Services Android SDK
Java
8
star
33

trira

A simple tool to sync Trello Cards with JIRA Tasks
JavaScript
8
star
34

modern-appdev-workshop

Workshop for enterprise enabled modern application development
TypeScript
6
star
35

aerogear-ios-sdk

AeroGear Services Swift SDK
Swift
6
star
36

graphql-home

AeroGear GraphQL projects and ideas
6
star
37

aerogear-unifiedpush-java-client

Java API to access the Unified Push Server
Java
6
star
38

charmil-host-example

Rhoas CLI as an Host example
Go
5
star
39

uniforms-ionic

Dynamic generation of React Forms using Ionic
TypeScript
5
star
40

unifiedpush-operator

☸️ Kubernetes operator for the AeroGear UnifiedPush Server
Go
4
star
41

native-android-example

Java
4
star
42

mobile-services-installer

Install Mobile Services on OpenShift
Shell
4
star
43

aerogear-digger-installer

Ansible role for installing AeroGear Digger on OpenShift
Groovy
4
star
44

ups-mock-data-loader

A tool that can be used to populate an UPS server with mock applications, variants and tokens
Java
3
star
45

unifiedpush-admin-client

Client library for Unified Push Administration
TypeScript
3
star
46

ios-showcase-template

Showcase template app for the AeroGear iOS SDK
Swift
3
star
47

aerogear-android-pipe

Pipe is a metaphor for connecting to a remote web service
Java
3
star
48

offix-react-native-example

Sample react app for offix.dev
TypeScript
3
star
49

charmil-plugin-example

Service registry artifacts commands from Rhoas as a plugin example
Go
2
star
50

ups-config-operator

Go
2
star
51

GSoC-2020

The landing page for potential Google Summer of Code students
2
star
52

aerogear-integration-tests

TypeScript
2
star
53

aerogear-push-js

Push support for cordova apps
TypeScript
2
star
54

mobile-security-service

Go
2
star
55

aerogear-parent

2
star
56

git-practical

Git Practical
2
star
57

unifiedpush-cli

A CLI to interact with the UnifiedPush Server
TypeScript
2
star
58

aerogear-android-core

Common components and interfaces which the rest of the AeroGear Android libraries depend on
Java
2
star
59

digger-android-slave-image

Dockerfile to create Jenkins slave images to build Android apps
Dockerfile
2
star
60

antora-ui

Styling used by antora to produce docs.aerogear.org
CSS
2
star
61

mobile-security

AeroGear Mobile Security https://docs.aerogear.org/mobile-security/latest/
HTML
1
star
62

aerogear-digger-node-client

Node.js integration lib
JavaScript
1
star
63

ag-cli

Aerogear Command Line Interface
TypeScript
1
star
64

charmil-starter

charmil-starter
Go
1
star
65

ups-operator-poc

A POC to demo how to convert an APB to an Ansible type operator
Python
1
star
66

docs.aerogear.org

Generated html for https://docs.aerogear.org
HTML
1
star
67

unifiedpush-cookbook

TypeScript
1
star
68

datasync-deployment

AeroGear DataSync Deployment
Shell
1
star
69

mobile-walkthrough

Data Sync Solution Pattern using GraphQL
1
star
70

aerogear-reactnative-push

React Native library for Unified Push
Java
1
star
71

xamarin-showcase-template

Xamarin showcase template
C#
1
star
72

test-suite

JavaScript
1
star
73

web-encrypted-storage

This repository is an example of how you can leverage the web storage api: https://developer.mozilla.org/en-US/docs/Web/API/Web_Storage_API to provide secure storage on your device using the web crypto api: https://developer.mozilla.org/en-US/docs/Web/API/Web_Crypto_API
TypeScript
1
star