Skip to content

Commit ed116cc

Browse files
Extend MinimalPermissionsGuidancePlugin to support delegated and application permissions (#1423)
* Add SchemeName optional parameter to MinimalPermissionsGuidancePlugin * Evaluate minimal permissions based on scheme name * Extend report to specify scheme name if defined * Update logging with scheme name if defined --------- Co-authored-by: Waldek Mastykarz <[email protected]>
1 parent cd8770e commit ed116cc

File tree

3 files changed

+52
-15
lines changed

3 files changed

+52
-15
lines changed

DevProxy.Plugins/Reporting/MinimalPermissionsGuidancePlugin.cs

Lines changed: 40 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ public sealed class MinimalPermissionsGuidancePluginConfiguration
1717
{
1818
public string? ApiSpecsFolderPath { get; set; }
1919
public IEnumerable<string>? PermissionsToExclude { get; set; }
20+
public string? SchemeName { get; set; }
2021
}
2122

2223
public sealed class MinimalPermissionsGuidancePlugin(
@@ -83,7 +84,7 @@ public override async Task AfterRecordingStopAsync(RecordingArgs e, Cancellation
8384

8485
foreach (var (apiSpec, requests) in requestsByApiSpec)
8586
{
86-
var minimalPermissions = apiSpec.CheckMinimalPermissions(requests, Logger);
87+
var minimalPermissions = apiSpec.CheckMinimalPermissions(requests, Logger, Configuration.SchemeName);
8788

8889
IEnumerable<string> excessivePermissions = [.. minimalPermissions.TokenPermissions
8990
.Except(Configuration.PermissionsToExclude ?? [])
@@ -100,7 +101,8 @@ public override async Task AfterRecordingStopAsync(RecordingArgs e, Cancellation
100101
TokenPermissions = [.. minimalPermissions.TokenPermissions.Distinct()],
101102
MinimalPermissions = minimalPermissions.MinimalScopes,
102103
ExcessivePermissions = excessivePermissions,
103-
UsesMinimalPermissions = !excessivePermissions.Any()
104+
UsesMinimalPermissions = !excessivePermissions.Any(),
105+
SchemeName = Configuration.SchemeName
104106
};
105107
results.Add(result);
106108

@@ -112,20 +114,45 @@ public override async Task AfterRecordingStopAsync(RecordingArgs e, Cancellation
112114

113115
if (result.UsesMinimalPermissions)
114116
{
115-
Logger.LogInformation(
116-
"API {ApiName} is called with minimal permissions: {MinimalPermissions}",
117-
result.ApiName,
118-
string.Join(", ", result.MinimalPermissions)
119-
);
117+
if (string.IsNullOrWhiteSpace(Configuration.SchemeName))
118+
{
119+
Logger.LogInformation(
120+
"API {ApiName} is called with minimal permissions: {MinimalPermissions}",
121+
result.ApiName,
122+
string.Join(", ", result.MinimalPermissions)
123+
);
124+
}
125+
else
126+
{
127+
Logger.LogInformation(
128+
"API {ApiName} is called with minimal permissions of '{SchemeName}' scheme: {MinimalPermissions}",
129+
result.ApiName,
130+
Configuration.SchemeName,
131+
string.Join(", ", result.MinimalPermissions)
132+
);
133+
}
120134
}
121135
else
122136
{
123-
Logger.LogWarning(
124-
"Calling API {ApiName} with excessive permissions: {ExcessivePermissions}. Minimal permissions are: {MinimalPermissions}",
125-
result.ApiName,
126-
string.Join(", ", result.ExcessivePermissions),
127-
string.Join(", ", result.MinimalPermissions)
128-
);
137+
if (string.IsNullOrWhiteSpace(Configuration.SchemeName))
138+
{
139+
Logger.LogWarning(
140+
"Calling API {ApiName} with excessive permissions: {ExcessivePermissions}. Minimal permissions are: {MinimalPermissions}",
141+
result.ApiName,
142+
string.Join(", ", result.ExcessivePermissions),
143+
string.Join(", ", result.MinimalPermissions)
144+
);
145+
}
146+
else
147+
{
148+
Logger.LogWarning(
149+
"Calling API {ApiName} with excessive permissions of '{SchemeName}' scheme: {ExcessivePermissions}. Minimal permissions are: {MinimalPermissions}",
150+
result.ApiName,
151+
Configuration.SchemeName,
152+
string.Join(", ", result.ExcessivePermissions),
153+
string.Join(", ", result.MinimalPermissions)
154+
);
155+
}
129156
}
130157

131158
if (unmatchedApiRequests.Any())

DevProxy.Plugins/Reporting/MinimalPermissionsGuidancePluginReport.cs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ public sealed class MinimalPermissionsGuidancePluginReportApiResult
1717
public required IEnumerable<string> Requests { get; init; }
1818
public required IEnumerable<string> TokenPermissions { get; init; }
1919
public required bool UsesMinimalPermissions { get; init; }
20+
public string? SchemeName { get; init; }
2021
}
2122

2223
public sealed class MinimalPermissionsGuidancePluginReport : IMarkdownReport, IPlainTextReport
@@ -39,14 +40,17 @@ public sealed class MinimalPermissionsGuidancePluginReport : IMarkdownReport, IP
3940

4041
foreach (var result in Results)
4142
{
43+
var permissionsHeader = "### Minimal permissions" + (string.IsNullOrWhiteSpace(result.SchemeName)
44+
? "" : $" for {result.SchemeName} scheme");
45+
4246
_ = sb.AppendLine(CultureInfo.InvariantCulture, $"## API: {result.ApiName}")
4347
.AppendLine()
4448
.AppendLine("### Requests")
4549
.AppendLine()
4650
.AppendJoin(Environment.NewLine, result.Requests.Select(r => $"- {r}"))
4751
.AppendLine()
4852
.AppendLine()
49-
.AppendLine("### Minimal permissions")
53+
.AppendLine(permissionsHeader)
5054
.AppendLine()
5155
.AppendJoin(Environment.NewLine, result.MinimalPermissions.Select(p => $"- `{p}`"))
5256
.AppendLine()
@@ -120,6 +124,8 @@ public sealed class MinimalPermissionsGuidancePluginReport : IMarkdownReport, IP
120124
foreach (var result in Results)
121125
{
122126
var apiTitle = $"API: {result.ApiName}";
127+
var permissionsHeader = "Minimal permissions" + (string.IsNullOrWhiteSpace(result.SchemeName)
128+
? "" : $" for {result.SchemeName} scheme") + ":";
123129
_ = sb.AppendLine()
124130
.AppendLine(apiTitle)
125131
.AppendLine(new string('-', apiTitle.Length))
@@ -129,7 +135,7 @@ public sealed class MinimalPermissionsGuidancePluginReport : IMarkdownReport, IP
129135
.AppendJoin(Environment.NewLine, result.Requests.Select(r => $"- {r}")).AppendLine()
130136
.AppendLine();
131137

132-
_ = sb.AppendLine("Minimal permissions:")
138+
_ = sb.AppendLine(permissionsHeader)
133139
.AppendJoin(", ", result.MinimalPermissions).AppendLine()
134140
.AppendLine();
135141

schemas/v1.3.0/minimalpermissionsguidanceplugin.schema.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,10 @@
1818
},
1919
"description": "The scopes to ignore and not include in the report. Default: ['profile', 'openid', 'offline_access', 'email'].",
2020
"default": ["profile", "openid", "offline_access", "email"]
21+
},
22+
"schemeName": {
23+
"type": "string",
24+
"description": "The name of the security scheme definition. Used to determine minimal permissions required for API calls."
2125
}
2226
},
2327
"required": [

0 commit comments

Comments
 (0)