API Integration

API connection to most tech stack applications to perform automated IAM provisioning.

Access Manager uses the REST API for each SaaS Provider to provision and deprovision users, groups, roles, etc.

If a SaaS Provider does not support API integration, has not been built yet, or needs to be provisioned in a different way for business reasons, Access Manager can use Slack notifications, email notifications, or automatically create or comment on GitLab issues to notify the provisioners for manual action required.

SaaS Provider API Services

Each SaaS Provider has a different API syntax, format and behavior. Behind the scenes, we create one or more Service Classes for each SaaS Provider that acts as a middleware between the Access Manager source code and the vendor's API. This allow us to have a consistent format for making API calls, similar to an Interface for a Repository when looking at it from object-oriented programming nomencalture, while allowing inconsistent customization behind the scenes to adapt to the needs and nuances of each provider API or SDK.

As an early preview of how API Service classes work, you can see the HackyStack source code for how we have done this in the past for AWS, GCP, and GitLab.

REST API Calls

The first iteration of API scripts is being built in the it-ops-laravel-scripts repository that has a simple architecture with reusable code for service-based architecture in the next iteration.

Creating a User

fastly-user:create

1// Create a User
2// https://developer.fastly.com/reference/api/account/user/#create-user
3$user = Http::withHeaders(['Fastly-Key' => config('services.fastly.token')])
4 ->post('https://api.fastly.com/user', [
5 'name' => $this->option('name'),
6 'login' => $this->option('login'),
7 'role' => $this->option('role')
8 ]);

Getting a User by ID

Source Code: fastly-user:get {user_id}

1// Get the specific user
2// https://developer.fastly.com/reference/api/account/user/#get-user
3$user = Http::withHeaders(['Fastly-Key' => config('services.fastly.token')])
4 ->get('https://api.fastly.com/user/'.$this->argument('user_id'));

Check if User Email Exists

https://gitlab.com/gitlab-com/business-technology/engineering/tools/it-ops-laravel-cli-scripts/-/blob/main/app/Console/Commands/FastlyUserExists.php

1// Get the current customer based on the API token
2// The ID of the customer is used in subsequent API calls
3// https://developer.fastly.com/reference/api/account/customer/#get-logged-in-customer
4$current_customer = Http::withHeaders(['Fastly-Key' => config('services.fastly.token')])
5 ->get('https://api.fastly.com/current_customer');
6
7// Get the list of users for the current customer
8// https://developer.fastly.com/reference/api/account/customer/#list-users
9$users_list = Http::withHeaders(['Fastly-Key' => config('services.fastly.token')])
10 ->get('https://api.fastly.com/customer/'.$current_customer->object()->id.'/users');
11$users_collection = collect($users_list->object());
12
13// Check if user exists with email address
14if($users_collection->contains('login', $this->argument('email'))) {
15 $user_profile = $users_collection->where('login', $this->argument('email'))->flatten()->toArray();
16 $this->line('<fg=green>Fastly User Exists - True - ID '.$user_profile[0]->id.' - Role '.$user_profile[0]->role.' - Created '.\Carbon\Carbon::parse($user_profile[0]->created_at)->toIso8601String().'</>');
17 if($this->option('delete')) {
18 $this->call('fastly-user:delete', [
19 'user_id' => $user_profile[0]->id
20 ]);
21 }
22} else {
23 $this->line('<fg=red>Fastly User Exists - False</>');
24}

Delete a User

https://gitlab.com/gitlab-com/business-technology/engineering/tools/it-ops-laravel-cli-scripts/-/blob/main/app/Console/Commands/FastlyUserDelete.php

1// Delete a User
2// https://developer.fastly.com/reference/api/account/user/#delete-user
3$user = Http::withHeaders(['Fastly-Key' => config('services.fastly.token')])
4 ->delete('https://api.fastly.com/user/'.$this->argument('user_id'));