All Projects → yahoojapan → athenz-client-sidecar

yahoojapan / athenz-client-sidecar

Licence: Apache-2.0 license
Moved to https://github.com/AthenZ/athenz-client-sidecar

Programming Languages

go
31211 projects - #10 most used programming language

Projects that are alternatives of or similar to athenz-client-sidecar

authorization-proxy
No description or website provided.
Stars: ✭ 31 (+121.43%)
Mutual labels:  authorization, sidecar, athenz
Gatekeeper
Lightweight library in C# for implementing roles-based access control (RBAC). With Gatekeeper, you can define users, roles, resources, and permissions, and authorize requests.
Stars: ✭ 25 (+78.57%)
Mutual labels:  authorization
react-native-auth-example
🔑 React Native APP 身份验证模块示例
Stars: ✭ 53 (+278.57%)
Mutual labels:  authorization
rust-spa-auth
Example application using a Vue frontend with Rust backend that has authentication + authorization.
Stars: ✭ 45 (+221.43%)
Mutual labels:  authorization
nl.fokkezb.loading
The widget provides a simple loading mask that can be easily styled and configured.
Stars: ✭ 96 (+585.71%)
Mutual labels:  archived
cliff-effects
Cliff effects guidance prototype (archived)
Stars: ✭ 30 (+114.29%)
Mutual labels:  archived
kibana4-vagrant
This is a vagrant virtual machine with an Kibana 4 (and ElasticSearch) instance. It belongs to a Kibana 4 tutorial on the following URL:
Stars: ✭ 39 (+178.57%)
Mutual labels:  archived
Authorization-Workshop
No description or website provided.
Stars: ✭ 14 (+0%)
Mutual labels:  authorization
swir
SWIR - Sidecar Written In Rust
Stars: ✭ 49 (+250%)
Mutual labels:  sidecar
mongoproxy
Lightweight proxy to collect MongoDb client metrics
Stars: ✭ 26 (+85.71%)
Mutual labels:  sidecar
XpringKit
XpringKit provides a Swift SDK for interacting with Xpring Protocols (XRP/PayID/ILP). This library is deprecated.
Stars: ✭ 23 (+64.29%)
Mutual labels:  archived
secret-sidecar
A Kubernetes init container that retrieves a secret from AWS Secrets Manager
Stars: ✭ 24 (+71.43%)
Mutual labels:  sidecar
folder-auth-plugin
Authorization Plugin for Jenkins that works on folders
Stars: ✭ 21 (+50%)
Mutual labels:  authorization
fedramp-automation
FedRAMP Automation
Stars: ✭ 175 (+1150%)
Mutual labels:  authorization
laravel-roles-abilities-tutorial
Tutorial demonstrating the implementation of roles and abilities in Laravel
Stars: ✭ 16 (+14.29%)
Mutual labels:  authorization
microsoft-teams-faqplusplus-app
DEPRECATED - This repository contains a deprecated version of the FAQ Plus app template. Please see the README file for more details and a link to the new repository
Stars: ✭ 47 (+235.71%)
Mutual labels:  archived
opa-kafka-plugin
Open Policy Agent (OPA) plug-in for Kafka authorization
Stars: ✭ 46 (+228.57%)
Mutual labels:  authorization
contentstats
DEPRECATED – See how many entries have been created for channels and structures in your Craft CMS website.
Stars: ✭ 29 (+107.14%)
Mutual labels:  archived
here-data-sdk-cpp
The HERE Data SDK for C++ is a modern, lightweight and modular SDK for the HERE platform
Stars: ✭ 47 (+235.71%)
Mutual labels:  authorization
authoreyes
A modern authorization plugin for Rails.
Stars: ✭ 13 (-7.14%)
Mutual labels:  authorization

Athenz client sidecar (moved)

⚠️ Warning: This repository has been moved to AthenZ/athenz-client-sidecar.

This repository is submitted to Athenz Open-Source Community. All ongoing developments and maintenances will continue in the new repository.

# update your local clone
git remote set-url origin https://github.com/AthenZ/athenz-client-sidecar.git

License: Apache GitHub release (latest by date) Docker Image Version (tag latest) CircleCI codecov Go Report Card GolangCI Codacy Badge GoDoc Contributor Covenant

logo

What is Athenz client sidecar

Athenz client sidecar is an implementation of Kubernetes sidecar container to provide a common interface to retrieve authentication and authorization credential from Athenz server.

Get Athenz N-token from client sidecar

Sidecar architecture (get N-token)

Whenever user wants to get the N-token, user does not need to focus on extra logic to generate token, user can access client sidecar container instead of implementing the logic themselves, to avoid the extra logic implemented by user. For instance, the client sidecar container caches the token and periodically generates the token automatically. For user this logic is transparent, but it improves the overall performance as it does not generate the token every time whenever the user asks for it.

Get Athenz Access Token from client sidecar

Sidecar architecture (get Access token)

User can get the access token from the client sidecar container. Whenever user requests for the access token, the sidecar process will get the access token from Athenz if it is not in the cache, and cache it in memory. The background thread will update corresponding access token periodically.

Get Athenz Role Token from client sidecar

Sidecar architecture (get Role token)

User can get the role token from the client sidecar container. Whenever user requests for the role token, the sidecar process will get the role token from Athenz if it is not in the cache, and cache it in memory. The background thread will update corresponding role token periodically.

Proxy HTTP request (add corresponding Athenz authorization token)

Sidecar architecture (proxy request)

User can also use the reverse proxy endpoint to proxy the request to another server that supports Athenz token validation. The proxy endpoint will append the necessary authorization (N-token or role token) HTTP header to the request and proxy the request to the destination server. User does not need to care about the token generation logic where this sidecar container will handle it, also it supports similar caching mechanism with the N-token usage.


Use Case

  1. GET /ntoken
    • Get service token from Athenz
  2. POST /accesstoken
    • Get access token from Athenz
  3. POST /roletoken
    • Get role token from Athenz
  4. GET /svccert
    • Get service certificate from Athenz
  5. /proxy/ntoken
    • Append service token to the request header, and send the request to proxy destination
  6. /proxy/roletoken
    • Append role token to the request header, and send the request to proxy destination

Specification

Get N-token from Athenz through client sidecar

  • Only Accept HTTP GET request.
  • Response body contains below information in JSON format.
Name Description Example
token The N-token generated v=S1;d=client;n=service;h=localhost;a=6996e6fc49915494;t=1486004464;e=1486008064;k=0;s=[signature]

Example:

{
  "token": "v=S1;d=client;n=service;h=localhost;a=6996e6fc49915494;t=1486004464;e=1486008064;k=0;s=[signature]"
}

Get access token from Athenz through client sidecar

  • Only accept HTTP POST request.
  • Request body must contains below information in JSON format.
Name Description Required? Example
domain Access token domain name Yes domain.shopping
role Access token role name (comma separated list) No user
proxy_for_principal Access token proxyForPrincipal name No proxyForPrincipal
expiry Access token expiry time (in second) No 1000

Example:

{
  "domain": "domain.shopping",
  "role": "user",
  "proxy_for_principal": "proxyForPrincipal",
  "expiry": 1000
}
  • Response body contains below information in JSON format.
Name Description Example
access_token Access token eyJraWQiOiIwIiwidHlwIjoiYXQrand0IiwiYWxnIjoiUlMyNTYifQ.eyJzdWIiOiJkb21haW4udHJhdmVsLnRyYXZlbC1zaXRlIiwiaWF0IjoxNTgzNzE0NzA0LCJleHAiOjE1ODM3MTY1MDQsImlzcyI6Imh0dHBzOi8venRzLmF0aGVuei5pbyIsImF1ZCI6ImRvbWFpbi5zaG9wcGluZyIsImF1dGhfdGltZSI6MTU4MzcxNDcwNCwidmVyIjoxLCJzY3AiOlsidXNlcnMiXSwidWlkIjoiZG9tYWluLnRyYXZlbC50cmF2ZWwtc2l0ZSIsImNsaWVudF9pZCI6ImRvbWFpbi50cmF2ZWwudHJhdmVsLXNpdGUifQ.[signature]
token_type Access token token type Bearer
expires_in Access token expiry time (in second) 1000
scope Access token scope (Only added if role is not specified, space separated) domain.shopping:role.user

Example:

{
  "access_token": "eyJraWQiOiIwIiwidHlwIjoiYXQrand0IiwiYWxnIjoiUlMyNTYifQ.eyJzdWIiOiJkb21haW4udHJhdmVsLnRyYXZlbC1zaXRlIiwiaWF0IjoxNTgzNzE0NzA0LCJleHAiOjE1ODM3MTY1MDQsImlzcyI6Imh0dHBzOi8venRzLmF0aGVuei5pbyIsImF1ZCI6ImRvbWFpbi5zaG9wcGluZyIsImF1dGhfdGltZSI6MTU4MzcxNDcwNCwidmVyIjoxLCJzY3AiOlsidXNlcnMiXSwidWlkIjoiZG9tYWluLnRyYXZlbC50cmF2ZWwtc2l0ZSIsImNsaWVudF9pZCI6ImRvbWFpbi50cmF2ZWwudHJhdmVsLXNpdGUifQ.F2x9_Q4GRmgRAXB0_tQRAWSwfJ9W3VtIoIVP1F4R19Ah8x1ml8jbxe88auOGmdElR8Gd2oQBNGMSyTkBgVBi9lRmYRpvYI94DN27zy5ZQzAPx_GgWshCbv8ebK9mHmcHkvGjJQzvoc7mgtKSRCZB4fC8-95c8Nb3BlebXWOz9evhO-xlkt5QYcavvSBzU6gNzZ7IjANTwIh4_iES-drWZOZ_yg4WS9wMpk1ycJRsdr5En5QMwQJEzcMRL-5-D8gLChXEESFSsY86ekd-fXOncP1N-V1xjfVURw_TzWKiIj6DFwRsMV1dTm9ffZC0tFKOKe9M3sUYdfkm0qWuEqLjfA",
  "token_type": "Bearer",
  "expires_in": 1000,
  "scope": "domain.shopping:role.user"
}

Get role token from Athenz through client sidecar

  • Only accept HTTP POST request.
  • Request body must contains below information in JSON format.
Name Description Required? Example
domain Role token domain name Yes domain.shopping
role Role token role name (comma separated list) No users
proxy_for_principal Role token proxyForPrincipal name No proxyForPrincipal
min_expiry Role token minimal expiry time (in second) No 100
max_expiry Role token maximum expiry time (in second) No 1000

Example:

{
  "domain": "domain.shopping",
  "role": "users",
  "proxy_for_principal": "proxyForPrincipal",
  "min_expiry": 100,
  "max_expiry": 1000
}
  • Response body contains below information in JSON format.
Name Description Example
token Role token v=Z1;d=domain.shopping;r=users;p=domain.travel.travel-site;h=athenz.co.jp;a=9109ee08b79e6b63;t=1528853625;e=1528860825;k=0;i=192.168.1.1;s=[signature]
expiryTime Role token expiry time (unix timestamp) 1528860825

Example:

{
  "token": "v=Z1;d=domain.shopping;r=users;p=domain.travel.travel-site;h=athenz.co.jp;a=9109ee08b79e6b63;t=1528853625;e=1528860825;k=0;i=192.168.1.1;s=s9WwmhDeO_En3dvAKvh7OKoUserfqJ0LT5Pct5Gfw5lKNKGH4vgsHLI1t0JFSQJWA1ij9ay_vWw1eKaiESfNJQOKPjAANdFZlcXqCCRUCuyAKlbX6KmWtQ9JaKSkCS8a6ReOuAmCToSqHf3STdKYF2tv1ZN17ic4se4VmT5aTig-",
  "expiryTime": 1528860825
}

Get service certificate from Athenz through client sidecar

  • Only Accept HTTP GET request.
  • Response body contains below information in JSON format.
Name Description Example
cert Service certificate <certificate in PEM format>

Example:

{
  "cert": "<certificate in PEM format>"
}

Proxy requests and append N-token authentication header

  • Accept any HTTP request.
  • Athenz client sidecar will proxy the request and append the N-token to the request header.
  • The destination server will return back to user via proxy.

Proxy requests and append role token authentication header

  • Accept any HTTP request.
  • Request header must contains below information.
Name Description Required? Example
Athenz-Role The user role name used to generate the role token Yes users
Athenz-Domain The domain name used to generate the role token Yes provider
Athenz-Proxy-Principal The proxy for principal name used to generate the role token Yes username

HTTP header Example:

Athenz-Role: users
Athenz-Domain: provider
Athenz-Proxy-Principal: username
  • The destination server will return back to user via proxy.

Configuration

Developer Guide

After injecting client sidecar to user application, user application can access the client sidecar to get authorization and authentication credential from Athenz server. The client sidecar can only access by the user application injected, other application cannot access to the client sidecar. User can access client sidecar by using HTTP request.

Example code

Get N-token from client sidecar

import (
    "encoding/json"
    "fmt"
    "net/http"

    "github.com/yahoojapan/athenz-client-sidecar/v2/model"
)

const scURL = "127.0.0.1" // sidecar URL
const scPort = "8081"

type NTokenResponse = model.NTokenResponse

func GetNToken() (*NTokenResponse, error) {
    url := fmt.Sprintf("http://%s:%s/ntoken", scURL, scPort)

    // make request
    res, err := http.Get(url)
    if err != nil {
        return nil, err
    }
    defer res.Body.Close()

    // validate response
    if res.StatusCode != http.StatusOK {
        err = fmt.Errorf("%s returned status code %d", url, res.StatusCode)
        return nil, err
    }

    // decode request
    var data NTokenResponse
    err = json.NewDecoder(res.Body).Decode(&data)
    if err != nil {
        return nil, err
    }

    return &data, nil
}

Get access token from client sidecar

import (
    "bytes"
    "encoding/json"
    "fmt"
    "net/http"

    "github.com/yahoojapan/athenz-client-sidecar/v2/model"
)

const scURL = "127.0.0.1" // sidecar URL
const scPort = "8081"

type AccessRequest = model.AccessRequest
type AccessResponse = model.AccessResponse

func GetAccessToken(domain, role, proxyForPrincipal string, expiry int64) (*AccessResponse, error) {
    url := fmt.Sprintf("http://%s:%s/accesstoken", scURL, scPort)

    r := &AccessRequest{
        Domain:            domain,
        Role:              role,
        ProxyForPrincipal: proxyForPrincipal,
        Expiry:            expiry,
    }
    reqJSON, _ := json.Marshal(r)

    // create POST request
    req, err := http.NewRequest(http.MethodPost, url, bytes.NewBuffer(reqJSON))
    if err != nil {
        return nil, err
    }
    req.Header.Set("Content-Type", "application/json")

    // make request
    res, err := http.DefaultClient.Do(req)
    if err != nil {
        return nil, err
    }
    defer res.Body.Close()

    // validate response
    if res.StatusCode != http.StatusOK {
        err = fmt.Errorf("%s returned status code %d", url, res.StatusCode)
        return nil, err
    }

    // decode request
    var data AccessResponse
    err = json.NewDecoder(res.Body).Decode(&data)
    if err != nil {
        return nil, err
    }

    return &data, nil
}

Get role token from client sidecar

import (
    "bytes"
    "encoding/json"
    "fmt"
    "net/http"

    "github.com/yahoojapan/athenz-client-sidecar/v2/model"
)

const scURL = "127.0.0.1" // sidecar URL
const scPort = "8081"

type RoleRequest = model.RoleRequest
type RoleResponse = model.RoleResponse

func GetRoleToken(domain, role, proxyForPrincipal string, minExpiry, maxExpiry int64) (*RoleResponse, error) {
    url := fmt.Sprintf("http://%s:%s/roletoken", scURL, scPort)

    r := &RoleRequest{
        Domain:            domain,
        Role:              role,
        ProxyForPrincipal: proxyForPrincipal,
        MinExpiry:         minExpiry,
        MaxExpiry:         maxExpiry,
    }
    reqJSON, _ := json.Marshal(r)

    // create POST request
    req, err := http.NewRequest(http.MethodPost, url, bytes.NewBuffer(reqJSON))
    if err != nil {
        return nil, err
    }
    req.Header.Set("Content-Type", "application/json")

    // make request
    res, err := http.DefaultClient.Do(req)
    if err != nil {
        return nil, err
    }
    defer res.Body.Close()

    // validate response
    if res.StatusCode != http.StatusOK {
        err = fmt.Errorf("%s returned status code %d", url, res.StatusCode)
        return nil, err
    }

    // decode request
    var data RoleResponse
    err = json.NewDecoder(res.Body).Decode(&data)
    if err != nil {
        return nil, err
    }

    return &data, nil
}

Get service certificate from client sidecar

import (
    "encoding/json"
    "fmt"
    "net/http"

    "github.com/yahoojapan/athenz-client-sidecar/v2/model"
)

const scURL = "127.0.0.1" // sidecar URL
const scPort = "8081"

type SvcCertResponse = model.SvcCertResponse

func GetSvcCert() (*SvcCertResponse, error) {
    url := fmt.Sprintf("http://%s:%s/svccert", scURL, scPort)

    // make request
    res, err := http.Get(url)
    if err != nil {
        return nil, err
    }
    defer res.Body.Close()

    // validate response
    if res.StatusCode != http.StatusOK {
        err = fmt.Errorf("%s returned status code %d", url, res.StatusCode)
        return nil, err
    }

    // decode request
    var data SvcCertResponse
    err = json.NewDecoder(res.Body).Decode(&data)
    if err != nil {
        return nil, err
    }

    return &data, nil
}

Proxy request through client sidecar (append N-token)

const (
    scURL  = "127.0.0.1" // sidecar URL
    scPort = "8081"
)

var (
    httpClient *http.Client // the HTTP client that use the proxy to append N-token header

    // proxy URL
    proxyNTokenURL    = fmt.Sprintf("http://%s:%s/proxy/ntoken", scURL, scPort)
)

func initHTTPClient() error {
    proxyURL, err := url.Parse(proxyNTokenURL)
    if err != nil {
        return err
    }

    // transport that use the proxy, and append to the client
    transport := &http.Transport{
        Proxy: http.ProxyURL(proxyURL),
    }
    httpClient = &http.Client{
        Transport: transport,
    }

    return nil
}

func MakeRequestUsingProxy(method, targetURL string, body io.Reader) (*[]byte, error) {
    // create POST request
    req, err := http.NewRequest(method, targetURL, body)
    if err != nil {
        return nil, err
    }

    // make request through the proxy
    res, err := httpClient.Do(req)
    if err != nil {
        return nil, err
    }
    defer res.Body.Close()

    // validate response
    if res.StatusCode != http.StatusOK {
        err = fmt.Errorf("%s returned status code %d", targetURL, res.StatusCode)
        return nil, err
    }

    // process response
    data, err := ioutil.ReadAll(res.Body)
    if err != nil {
        return nil, err
    }

    return &data, nil
}

Proxy request through client sidecar (append role token)

const (
    scURL  = "127.0.0.1" // sidecar URL
    scPort = "8081"
)

var (
    httpClient *http.Client // the HTTP client that use the proxy to append role token header

    // proxy URL
    proxyRoleTokenURL = fmt.Sprintf("http://%s:%s/proxy/roletoken", scURL, scPort)
)

func initHTTPClient() error {
    proxyURL, err := url.Parse(proxyRoleTokenURL)
    if err != nil {
        return err
    }

    // transport that use the proxy, and append to the client
    transport := &http.Transport{
        Proxy: http.ProxyURL(proxyURL),
    }
    httpClient = &http.Client{
        Transport: transport,
    }

    return nil
}

func MakeRequestUsingProxy(method, targetURL string, body io.Reader, role, domain, proxyPrincipal string) (*[]byte, error) {
    // create POST request
    req, err := http.NewRequest(method, targetURL, body)
    if err != nil {
        return nil, err
    }

    // append header for the proxy
    req.Header.Set("Athenz-Role", role)
    req.Header.Set("Athenz-Domain", domain)
    req.Header.Set("Athenz-Proxy-Principal", proxyPrincipal)

    // make request through the proxy
    res, err := httpClient.Do(req)
    if err != nil {
        return nil, err
    }
    defer res.Body.Close()

    // validate response
    if res.StatusCode != http.StatusOK {
        err = fmt.Errorf("%s returned status code %d", targetURL, res.StatusCode)
        return nil, err
    }

    // process response
    data, err := ioutil.ReadAll(res.Body)
    if err != nil {
        return nil, err
    }

    return &data, nil
}

We only provided golang example, but user can implement a client using any other language and connect to sidecar container using HTTP request.

Deployment Procedure

  1. Inject client sidecar to your K8s deployment file.

  2. Deploy to K8s.

    kubectl apply -f injected_deployments.yaml
  3. Verify if the application running

    # list all the pods
    kubectl get pods -n <namespace>
    # if you are not sure which namespace your application deployed, use `--all-namespaces` option
    kubectl get pods --all-namespaces
    
    # describe the pod to show detail information
    kubectl describe pods <pod_name>
    
    # check application logs
    kubectl logs <pod_name> -c <container_name>
    # e.g. to show client sidecar logs
    kubectl logs nginx-deployment-6cc8764f9c-5c6hm -c athenz-client-sidecar

License

Copyright (C) 2018 Yahoo Japan Corporation Athenz team.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

Contributor License Agreement

This project requires contributors to agree to a Contributor License Agreement (CLA).

Note that only for contributions to the athenz-client-sidecar repository on the GitHub, the contributors of them shall be deemed to have agreed to the CLA without individual written agreements.

About releases

  • Releases
    • GitHub release (latest by date)
    • Docker Image Version (tag latest)

Authors

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].