TSDN
CIAMCIAM for Developers 2


CIAM For Developers

If you are integrating an external vendor web service, please skip to the Service Providers in PingFederate section.

Integrating your Topcon Web Service with CIAM might seem daunting at first, but the goal of this section is to guide you through the process and help you get started.

Key Point: It's just OAuth 2.0! Don’t worry. Yes, we have some claims in the JWT access tokens to help you protect resources by tenancy, and yes, we have Policy language in OPA’s Rego to secure your Resource Server—but at its core, CIAM is just OAuth 2.0.

By leveraging PingFederate, CIAM supports most OAuth 2.0 flows, including Authorization Code Flow, Client-Credentials, Native App Flow, and token exchange. If you aren’t familiar with OAuth 2.0, read up on it here.

For all these flows, you’ll need OAuth2.0 client-credentials for your Web Service or native application. You can create your Web Service’s client-credentials by signing into the My Topcon self-service dashboard with your Topcon domain credentials. Alternatively, you can sign in to the PAP REST API here and create client-credentials using the OpenAPI web interface, Postman, or curl.

Things you’ll need:

  • User with Information-Technology Profile in a Topcon Engineering Business Partner. This access allows you to create a Client entity.
  • OAuth 2.0 scopes. If you’re developing a new Topcon Web Service or migrating an existing one to CIAM, you’ll need to work with the CIAM team to register the OAuth 2.0 scopes you want to use to secure your Resource Server. While Topcon hasn’t historically used scopes, we are now requiring them to protect Resource Server APIs. Please collaborate with us to define sensible scopes for your Web Service, which we’ll register with PingFederate to allow your clients to mint access tokens with those scopes.
  • An App Policy for your application. An App Policy is part of the IT-managed OPA bundle and governs OAuth 2.0 Client creation in PingFederate. It states what OAuth2.0 flows, claims, scopes and Resource Servers are permitted for your application. Work with us to create an App Policy tailored to your Web Service—it’s simple, just a JSON object in the core OPA bundle. You can view examples here.

If you’re missing any of these things, please raise an IT-Service desk ticket for the CIAM service manager.

Once you have created an OAuth Client, you can use the service endpoints to perform the required OAuth2.0 flow.

Phased Migration

This section outlines the phased development and migration plan for CIAM. The CIAM project was developed in line with these phases, meaning there are authorization flows and tokens for each phase. This phased approach facilitates incremental migration of an existing web service or app to CIAM.

Phase 1 (Migrate by April 2025)

In the first phase, you can leave most of your code unchanged—you're simply switching the OAuth 2.0 Authorization Server (AS) from the old TRAPI AS to the new PingFederate AS. In Summary, this means you'll need to change your apps configuration to use:

  • new authorize and token endpoints
  • a new secret
  • some scopes

To migrate to Phase 1, work with the CIAM Service Manager to get a new OAuth2.0 Client:

  • Your new PingFederate OAuth2.0 Client will have the same client id as your old TRAPI client.
  • Your new PingFederate OAuth2.0 Client will have a new secret.
  • Your client will have the app_policy field set to "openid". The openid App Policy is suitable for all phase1 migration clients.
  • Your client will have the authentication_policy field set to "phase1".
  • Your client will have the bypass_approval field set to true if it is an internal Topcon application.
  • You will need to adjust your applications code and configuration to:
    • Use the new secret
    • Use the new authorize and token endpoints listed in the service endpoints section below.
    • Use scopes. In the past, we didn't require scopes. Going forward, we require the use of scopes for all Resource Servers.
      • You will need the "openid" and "profile" scopes.
      • You will need scopes related to parts of the TRAPI API you use. See the new TRAPI scopes below, and add the scope for each TRAPI resource your application uses.
  • Your old client will continue to work at TRAPI, so you can easily rollback if needed.

The trapi scopes are:

  • "topcon.trapi.assets",
  • "topcon.trapi.cases",
  • "topcon.trapi.dealers",
  • "topcon.trapi.ecommerce",
  • "topcon.trapi.leads",
  • "topcon.trapi.licenses",
  • "topcon.trapi.orders",
  • "topcon.trapi.products",
  • "topcon.trapi.sims",
  • "topcon.trapi.sites",
  • "topcon.trapi.teams",
  • "topcon.trapi.users"

Please deploy to QA and test. Then deploy to PROD and test. Remember your old clients continue to work, so you can easily roll back if needed.

No brand bar changes are required for phase 1.

Phase 1.5 (Migrate by October 2025)

Phase 1.5 was not part of the original plan, which is why it has the "point 5" suffix. It was designed as an intermediary phase to support the deprecation of Password Flow in favor of Native Apps using PKCE.

But this phase also has the added benefit of simplifying the migration of an existing web service or app to CIAM.

In Phase 1.5, the Team Selection concept is moved away from the stateful Topcon Rest API (TRAPI SetCurrentTeam) and built into the new PingFederate OAuth 2.0 authorization step. A Phase 1.5 token includes the current team as a claim, meaning you need to remove any code related to team selection from your product (both web and rich client). Phase 1.5 migration is more involved then, because you have to change your applications user interface and logic to remove all team selection concepts - team selection is done for you by CIAM!

In the old system, an access token was tied to the user (an email address) and the token granted access to resources for multiple teams (tenancies). This was particularly problematic when some users (like dealers) had access to hundreds of teams.

To implement or migrate to Phase 1.5, you will:

  • Remove team selection logic from your application
  • Create a Phase 1.5 Client
  • Obtain tokens using an OAuth 2.0 flow (Code Flow in this example)
  • Use these tokens in TRAPI and for transfer

Removing Team Selection Logic

Any brand bar, menu options etc which allow the user to select a team needs to be removed from your application. Any use of TRAPI for team selection and getting the current team needs to be removed from your application. Any stateful logic about the current team needs to be removed from your application.

When other applications use transfer tokens to get access to your application, you will need to get a TRAPI token; and so continue to use the TRAPI client ID and secret for this only. Your API will need to remain backwards compatible for when applications are using transfer tokens to access your API, including team selection logic in your API.

If you have any questions about this, please work with the CIAM team to discuss your particular use cases.

Other user interface changes will include using the Phase 1.5 brand bar (TODO add documentation link).

Creating a Phase 1.5 Client

Work with the CIAM Service Manager to get an App Policy and Client created in the PAP. The Client must have the authentication_policy set to "phase1.5".

Note: If you already have a Phase 1 client, you can simply change the authentication_policy to "phase1.5".

Obtaining Tokens Using an OAuth 2.0 Flow

In Phase 1.5, OAuth 2.0 flows guide the user through screens to input:

  • Username and Password
  • Team
  • Approval (optional)

This results in the issuance of a token, which can be used as a Bearer Token for TRAPI.

In a browser flow, credentials and team settings are persisted in cookies.

  • You can override the Team setting by supplying the additional parameter switch=bp to your login URL.
  • You can override the credentials by logging out.

Phase 1.5 tokens are JWTs that contain the following fields:

  • client_id: PingFederate client ID that created this token
  • exp: Token expiry, in seconds since the epoch
  • iss: String identifying the issuer
  • jti: Unique identifier for this JWT
  • orgunit: (Topcon field) Obfuscated orgunit ID
  • scope: Scopes granted for the token
  • sub: Internal system identifier for the user
  • tcph: (Topcon field) Identifies the Topcon Phase (will be 1.5)
  • username: (Topcon field) User's email

For example:

{
       "client_id": "8da9633e-6e1c-4292-a464-23e7ced0de29",
       "exp": 1698719430,
       "iss": "ping-qa",
       "jti": "bzrRX0HaebiO",
       "orgunit": "q6awkKO3q7elmpfWm5qmurF/qLWkpZuq",
       "scope": "openid",
       "sub": "e731d351-9515-4997-8f62-5bce2463d793",
       "tcph": "1.5",
       "username": "xxxxxx@yyyyyy.com"
}

Using these Tokens at TRAPI

Phase 1.5 tokens do not contain explicit team data; this can be obtained from TRAPI:

GET ${TRAPI_HOST}/v1/teams?defaultOnly=true where TRAPI_HOST is

will return an array of the shape

[
    {
        "id": "a2L1bxxxxxxxxxxEAM",
        "name": "XXX XXXXX XX",
        "role": "Admin",
        "isDealer": false,
        "isDefault": true
    }
]

Phase 2

Phase 2 of CIAM introduces:

  • The PAP and most PAP entities.
  • The PRP, which is required to run OPA as the PDP and PEP.
  • New Phase 2 authentication flows that determine the Business Partner based on the email of the signing-in Identity.

To implement or migrate to Phase 2, you will:

  • Remove all user and access management from your application.
  • Create a Phase 2 Client.
  • Write your OPA Rego policies and upload them to the PAP.
  • Provision a PDP.
  • Provision a PEP.

Here’s a bit more detail:

For an existing Topcon Web Service (Resource Server), migrating to Phase 2 involves:

  • Evaluating the migration effort: It might not make business sense to migrate your web service.
  • Removing any user or identity management code from your Web Service—CIAM will centrally manage this.
    • We recommend deleting this code entirely rather than adapting it for CIAM. The goal is to use CIAM policies for access management instead of any existing logic.
  • Switching your current access management to CIAM's PEP.
    • By using OPA Rego and adding a PIP for your product, you can transition to a CIAM PEP without altering your REST API. Work with us to determine the best approach, but we should be able to keep your service backwards compatible.
    • If necessary, migrate some of your existing user access management to CIAM PAP before deleting them. We'll assist you with this process.

For a new Topcon Web Service (Resource Server), migrating to Phase 2 involves:

  • Starting your project with a PDP and PEP. We have templates for many technologies, and if we don't have one, we’ll create it.
  • Use the CIAM PEP—don't build your own access management solution. If you think you can't, talk to us.

For a client or service that isn’t a Resource Server (i.e., doesn't protect resources), migrating to Phase 2 means:

  • Simply creating the OAuth 2.0 Client.

Creating a Client

Work with the CIAM Service Manager to create an App Policy and Client in the PAP. The Client must have the authentication_policy set to "phase2".

Note: If you already have a Phase 1 or Phase 1.5 client, you can simply change the authentication_policy to "phase2".

Writing OPA Rego Policies for Your Topcon Web Service

Remember: If you are integrating an external vendor web service, please ignore these phases and skip to the Service Providers in PingFederate section.

Topcon's CIAM uses OPA Rego to implement policies for PDP (Policy Decision Point) evaluation. This centralized approach simplifies user lifecycle management and provides a better user experience.

Key Point: This approach enables products to integrate effectively by using common resource names (TRNs) and common policies for resource protection - we can finally create well-integrated Web Services.

We recommend learning Rego, which can be done in a few hours.

Policy Information Points (PIPs)

The first step in migrating an existing service is to provide a Policy Information Point (PIP) for your service. A PIP maps your service’s internal IDs (e.g., org unit IDs) to CIAM Business Partner IDs. A PIP is essentially a REST API endpoint. If you are developing a new service and need IDs in your paths, please ensure they are canonical.

Here is an example of a PIP from Sitelinks Phase 2 integration:

package topcon.resources.sitelink

import rego.v1
import data.topcon.jwt

default owner_id := ""

topcon_edge_host = "sitelink.edge-router"

to_owner_id(tcbp) = result if {
    url := sprintf("https://%s/teams/%s", [topcon_edge_host, tcbp])
    response := http.send({
        "method": "get",
        "url": url,
        "cache": true,
        "caching_mode": "deserialized",
        "force_json_decode": true 
    })
    response.status_code == 200
    result = response.body.owner_uuid
}

owner_id = result if {
    result = to_owner_id(jwt.valid_claims.tcbp)
}

In this Rego, the rule owner_id allows Sitelink policies to resolve the Business Partner in the incoming JWT to a Sitelink Owner ID.

Sitelink has added a PIP at https://sitelink.edge-router/teams/{id} to resolve a CIAM Business Partner to a Sitelink Owner ID. Rego accesses this using the http.send function, which respects caching directives in the HTTP response. This means that OPA will call the http.send function the first time a Business Partner needs to be resolved, and then obey the cache directives. Future resolutions of the same Business Partner will be retrieved from the OPA cache at zero cost, since the mapping between the CIAM Business Partner and the Sitelink Owner is immutable (the cache only needs to be invalidated when necessary).

Adding this PIP ensures that the Sitelink API remains unchanged (the API routes still include Sitelink Owner IDs). The Sitelink Rego policies can translate incoming JWT Business Partner IDs to Sitelink Owner IDs and confirm that the Owner ID in the route matches.

Input Format for HTTP Requests

We have chosen the convention from Envoy as the schema for our HTTP input to our Rego policies. Here is the schema:

{
  "attributes": {
    "request": {
      "http": {
        "headers": {
          "Authorization": "Bearer xyz"
        },
        "host": "",
        "method": "GET",
        "path": "https://myservice.topcon.com/some/path"
      }
    }
  },
  "parsed_path": ["some", "path"]
}
Adding Rego Rules for Web Service API Endpoints

After adding your PIPs, you need to write Rego rules that cover all of your Web Service API endpoints.

Here is a single endpoint from Sitelink's Phase 2 Rego:

package topcon.resources.sitelink

import rego.v1
import data.topcon.secops
import data.topcon.jwt

# GetOwner
allow if {
    secops.allow
    "GET" == input.attributes.request.http.method
    ["siteowner", "v1", "owners", owner_id] == input.parsed_path
    jwt.has_scope("sitelink.owners")
}

This rule states that the incoming REST request is allowed if:

  • Sec-ops says so (sec-ops can check geo-ip etc).
  • Is a GET request.
  • Has the path /siteowner/v1/owners/{owner_id}, where owner_id is resolved by the PIP rule from the incoming JWT CIAM Business Partner (enforcing tenancy protection).
  • Has the scope sitelink.owners.
  • The CIAM library data.topcon.jwt is used. There are other libraries available to assist, such as data.topcon.rbac, which performs Role-Based Access Control (RBAC) enforcement.

Key Point: All services protected by CIAM must use scopes.

That should give you a good starting point. For more information, please review the PAP's own PEP Rego here, read the Rego documentation here, and work with us to plan your Web Service migration.

Once you have the Rego code for your Web Service, along with unit tests for each route, you are ready to upload your policies to the PAP.

Structuring Your Rego Rules into an OPA Bundle

You need to structure your OPA Rego and JSON data into an OPA Bundle, following convention. You can read more about OPA Bundles here. Topcon has an OPA Bundle server that our PDPs long-poll. The bundle endpoint is detailed in the Service Endpoints section below. As bundles are updated in the PAP, unit tests are executed. If all unit tests pass, the bundle changes are applied to any OPA Agent that requires the updated bundle. Each Resource Server (e.g., Sitelink, Rinexstore, Magnet Data Converter) will have its own policy bundle.

A bundle is simply a gzipped tarball, so your source code repository should have a folder structure containing Rego and JSON files (policies and policy data, respectively). During the CI/CD process for your Web Service, this folder will undergo unit testing, then be tar-gzipped and uploaded to the PAP.

The folder structure should look like this:

topcon\
  resources\
    {resource}\
      xyz.rego
      data.json
  • Every bundle must have a root topcon folder with a child resources folder.

  • The {resource} folder name should be replaced with your Resource Server name, as agreed upon with the CIAM service manager (e.g., "sitelink").

  • Any policy data must be in a file named data.json (this is an OPA convention).

  • Your folder structure is converted into dot-notation in Rego files, so accessing data from data.json would look like data.topcon.resources.sitelink.blah.

  • You can add more folders under your Resource Server folder to organize your policy Rego code and data into separate files.

Uploading your Policy Bundle to the PAP

To upload your bundle:

  • ensure your rego unit tests pass
  • PUT your gzipped tarball to your services route (see [Service Routes] below(#service-endpoints))
  • Use the bearer token issued by the CIAM service manager for your resource service

Note: the CIAM bundle service will run your unit tests, and only accept your bundle if they pass. This step is not implemented yet, but will be so ensure your tests pass.

Deploying your own PDP and PEP

Deploying your own PDP

Part of the design of Topcon's CIAM is to ensure low latency and fast policy decision making. To allow this to happen, we push the decision making engine right into your data-centre as a side-car. The decision making engine is an OPA agent.

Information on running OPA is found here.

You can run OPA as a sidecar in your ingress HA proxy, run it as a separate service in your kubernates cluster, run it as a lambda, run it as a library if you are using go-lang, or use existing OPA integrations in Traefik, Envoy, Nginx etc.

The key part of deploying OPA is:

  • providing the OPA configuration
  • getting credentials for your configuration

Here is an example OPA configuration for the Resource Server called "example-service":

{
  "services": {
    "prpbundle": {
      "url": "https://prpbundle.us.qa.auth.topcon.com",
      "credentials": {
        "bearer": "xyz"
      }
    }
  },
  "bundles": {
    "prpbundle": {
      "resource": "/opa/resource/example-service",
      "polling": {
        "long_polling_timeout_seconds": 30,
      }
    }
  },
  "decision_logs": {
    "console": false
}
  • Use the bearer token issued by the CIAM service manager for your resource service

If you want reference implementations for Traefik, Envoy etc. please talk to us.

Deploying your own PEP

Deploying your own PEP is to configure your existing HA proxy to use the OPA middleware.

This configuration is specific for AWS API Gateway, Envoy, Traefik or Nginx etc.

Note: We have some existing configurations for these, but they need adding here.

Special OAuth2 Use Cases

Native App

TODO

Token Exchange

Topcon's CIAM implements a global (edge-local) STS service for delegating user permissions for backing services.

This STS service adheres to RFC 8693.

Any microservice (service-A) wishing to delegate an incoming token to itself as an actor for a call-out to an upstream service (service-B) can do so by use of the STS service.

What is needed?

  • Client-Credentials for service-A which has the scopes needed for the call-out to upstream services.
  • URL of the STS.
  • Work with CIAM service manager team to set the policies for the delegation. This is policy based, so you can raise a PR.
  • Make a token call to the STS service - see the Service Endpoints section below for the STS endpoint. This call is accordance with RFC 8693.
  • The incoming user token is used as the subject_token with subject_token_type being "urn:ietf:params:oauth:token-type:access_token".
  • A client credential access token from service-B is used as the actor_token with the actor_token_type being "urn:ietf:params:oauth:token-type:access_token".
  • The same client credentials are used for the STS token service.

Service Providers in PingFederate

This section relates to integrating external vendor procured web services (such as our e-learning services). 3rd-Party web services accessing CIAM for OAuth2.0 authentication for Topcon Web Service API access are not in mind in this section.

If you wish to integrate an external vendor service with CIAM, we will need to do some Ping Federate Service Provider setup. We can setup integrations to get your application automatically creating Business Partner and User related entities. We can setup Service Provider adapters to mint tokens needed for your application to work. Please get in touch with the CIAM service manager to start this work.

Service Endpoints

DEV

Endpoints for integrating an OAuth2.0 client with CIAM:

Endpoints for deploying your own PDP OPA agent:

Note you'll need to register a Resource Server name, and be issued with bearer tokens needed to connect to the prpbundle service.

Other CIAM endpoints:

QA

Endpoints for integrating an OAuth2.0 client with CIAM:

Endpoints for deploying your own PDP OPA agent:

Note you'll need to register a Resource Server name, and be issued with bearer tokens needed to connect to the prpbundle service.

Other CIAM endpoints:

PRODUCTION

Endpoints for integrating an OAuth2.0 client with CIAM:

Endpoints for deploying your own PDP OPA agent:

Note you'll need to register a Resource Server name, and be issued with bearer tokens needed to connect to the prpbundle service.

Other CIAM endpoints: