Approve/Revoke API Keys in Apigee Through PS

on Monday, April 2, 2018

The Apigee API Gateway grants access using API Keys (in this example). And, those keys are provisioned for each application that will use an API. This can be a bit confusing, because when you first sign up to use an API, you think that you’re going to get an API Key. But, that’s not the case. It’s your application that gets the key. This grants finer grained control of what applications have access to what, and allows for malicious activity to have a narrower impact. It does make the REST API Management backend a little confusing, as you always need to specify a developers email address when updating an application. The application’s are owned by a developer, so you have to know the developer before updating the application.

There’s a little more confusion because Applications don’t have direct access to APIs. Applications are given approval to use API Products. And, those API Products grant access to different API Proxies. This layer of abstraction is helpful when you want to make a very custom made API Product for an individual customer. And that can happen more often than you might expect.

image

So, in order to approve or revoke an API key on an Application you will actually need:

  • The developers email address
  • The application name
  • The API product name
  • And, either to approve or revoke the status

This script will use the developer email address and application name to look up the status of the application. If no specific API product name is given then the status of Approve or Revoke will be applied to the Application and all associated API Products. If a specific API product name is given, then only that API Products' status will be updated.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
$global:ApigeeModule = @{}
$global:ApigeeModule.ApiUrl = "https://api.enterprise.apigee.com/v1/organizations/{org-name}"
$global:ApigeeModule.AuthHeader = @{ Authorization = "Basic {base64-encoded-credentials}" }
 
<#
.SYNOPSIS
    Makes a call to the Apigee Management API. It sets the approved/revoked status on
    an individual API Product for an Appliation. If not individual API Product is specified
    then the status will change for the Application and all associated API Products.
 
.PARAMETER Email
    The developer email address that owns the Application
 
.PARAMETER AppName
    The application to updated
 
.PARAMETER ApiProductName
    The individual API product to update (optional).
 
.PARAMETER Status
    Either 'approved' or 'revoked'
 
.EXAMPLE
    $appInfo = Set-ApigeeDeveloperAppStatus -Email it@company.org -AppName someapp -ApiProductName calendard_api -Status approved
#>
Function Set-ApigeeDeveloperAppStatus {
[CmdletBinding()]
Param (
    [Parameter(Mandatory = $true)]
    [string] $Email,
    [Parameter(Mandatory = $true)]
    [string] $AppName,
    [Parameter(Mandatory = $false)]
    [string] $ApiProductName = [String]::Empty,
    [Parameter(Mandatory = $true)]
    [ValidateSet("approved","revoked")]
    [string] $Status
)
 
    $action = "approve"
    if($Status -eq "revoked") { $action = "revoke" }
 
 
    # check the app exists (maybe use error handling here?)
    $appPath = "/developers/$Email/apps/$AppName"
    $app = Invoke-ApigeeRest -ApiPath $appPath
 
 
    # api key/oauth key are stored in the first credentials
    # (all api products are stored within this credential)
    $creds = $app.credentials[0]
 
    $keysPath = "$appPath/keys"
    $keyPath = "$keysPath/$($creds.consumerKey)"
 
 
    # if no api product is selected, approve or deny the entire developer app
    # (the api products are going to be approved/revoked as well)
    if($ApiProductName -eq [String]::Empty) {
 
        # it's very rare that the App will have it's status changed, but just in case ...
        if($app.status -ne $Status) {
            $path = $appPath + "?action=$action"
            Write-Verbose "Setting app '$AppName' ($Email) to status '$Status'"
            Invoke-ApigeeRest -ApiPath $path -Method Post -ContentType "application/octet-stream"
        }
     
 
        # if no api product is selected,
        # then approve or deny the entire set of api products
        foreach($apiProduct in $creds.apiProducts) {
            if($apiProduct.status -ne $Status) {
                $path ="$keyPath/apiproducts/$($apiproduct.apiproduct)?action=$action"
                Write-Verbose "Setting api product '$($apiproduct.apiproduct)' on app '$AppName' ($Email) to status '$Status'"
                Invoke-ApigeeRest -ApiPath $path -Method Post -ContentType "application/octet-stream"
            }
        }
 
    } else {
    # if an api product name is given, then only update that product
 
        # check the api product exists
        $apiProduct = $creds.apiProducts |? apiproduct -eq $ApiProductName
        if(-not $apiProduct) {
 
            Write-Verbose "Could not find api product '$ApiProductName' for app '$AppName' ($Email)"
 
        } else {
             
            $path = "$keyPath/apiproducts/$($ApiProductName)?action=$action"
            Write-Verbose "Setting api product '$ApiProductName' on app '$AppName' ($Email) to status '$Status'"
            Invoke-ApigeeRest -ApiPath $path -Method Post -ContentType "application/octet-stream"
 
        }
    }
     
 
    $app = Invoke-ApigeeRest -ApiPath $appPath
    return $app
}
 
 
 
<#
.SYNOPSIS
    Makes a call to the Apigee Management API. It adds the authorization header and
    uses the root url for our organizations management api endpoint ($global:ApigeeModule.ApiUrl).
    This returns the body of the response as a string.
 
.PARAMETER ApiPath
    The sub path that will be added onto $global:ApigeeModule.ApiUrl.
 
.EXAMPLE
    $developers = Invoke-ApigeeMethod -ApiPath "/developers"
#>
Function Invoke-ApigeeRest {
[CmdletBinding()]
Param (
    [Parameter(Mandatory = $true)]
    [string] $ApiPath,
    [ValidateSet("Default","Delete","Get","Head","Merge","Options","Patch","Post","Put","Trace")]
    [string] $Method = "Default",
    [object] $Body = $null,
    [string] $ContentType = "application/json",
    [string] $OutFile = $null
)
 
    if($ApiPath.StartsWith("/") -eq $false) {
        $ApiPath = "/$ApiPath"
    }
    $Uri = $global:ApigeeModule.ApiUrl + $ApiPath
 
    if($Body -eq $null) {
        $result = Invoke-RestMethod `
                    -Uri $Uri `
                    -Method $Method `
                    -Headers $global:ApigeeModule.AuthHeader `
                    -ContentType $ContentType `
                    -OutFile $OutFile
    } else {
        $result = Invoke-RestMethod `
                    -Uri $Uri `
                    -Method $Method `
                    -Headers $global:ApigeeModule.AuthHeader `
                    -Body $Body `
                    -ContentType $ContentType `
                    -OutFile $OutFile
    }
     
    return $result
}

0 comments:

Post a Comment


Creative Commons License
This site uses Alex Gorbatchev's SyntaxHighlighter, and hosted by herdingcode.com's Jon Galloway.