Skip to content

Commit cc30104

Browse files
committed
RBAC: Incrementally add new @secured annotations to OSS API endpoints (#9807)
1 parent 98720ac commit cc30104

23 files changed

+178
-116
lines changed

airbyte-commons/src/main/java/io/airbyte/commons/auth/AuthRoleConstants.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
*/
1010
public final class AuthRoleConstants {
1111

12+
// TODO: replace "ADMIN" with "INSTANCE_ADMIN" and remove "EDITOR", "OWNER", etc
13+
// once all @Secured annotations are migrated to the new organizatin/workspace RBAC roles.
1214
public static final String ADMIN = "ADMIN";
1315
public static final String AUTHENTICATED_USER = "AUTHENTICATED_USER";
1416
public static final String EDITOR = "EDITOR";
@@ -24,7 +26,11 @@ public final class AuthRoleConstants {
2426
public static final String WORKSPACE_ADMIN = "WORKSPACE_ADMIN";
2527
public static final String WORKSPACE_EDITOR = "WORKSPACE_EDITOR";
2628
public static final String WORKSPACE_READER = "WORKSPACE_READER";
27-
public static final String WORKSPACE_MEMBER = "WORKSPACE_MEMBER";
29+
30+
// the 'SELF' role is used to secure endpoints that should only be called by the user themselves.
31+
// For example, creating an Airbyte User record for a particular authUserId should only be done
32+
// by callers that have authenticated as that authUserId.
33+
public static final String SELF = "SELF";
2834

2935
private AuthRoleConstants() {}
3036

airbyte-server/src/main/java/io/airbyte/server/apis/AttemptApiController.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@
55
package io.airbyte.server.apis;
66

77
import static io.airbyte.commons.auth.AuthRoleConstants.ADMIN;
8+
import static io.airbyte.commons.auth.AuthRoleConstants.ORGANIZATION_READER;
89
import static io.airbyte.commons.auth.AuthRoleConstants.READER;
10+
import static io.airbyte.commons.auth.AuthRoleConstants.WORKSPACE_READER;
911

1012
import io.airbyte.api.generated.AttemptApi;
1113
import io.airbyte.api.model.generated.AttemptInfoRead;
@@ -43,7 +45,7 @@ public AttemptApiController(final AttemptHandler attemptHandler) {
4345
@Post(uri = "/get_for_job",
4446
processes = MediaType.APPLICATION_JSON)
4547
@ExecuteOn(AirbyteTaskExecutors.IO)
46-
@Secured({READER})
48+
@Secured({READER, WORKSPACE_READER, ORGANIZATION_READER})
4749
@SecuredWorkspace
4850
public AttemptInfoRead getAttemptForJob(final GetAttemptStatsRequestBody requestBody) {
4951
return ApiHelper
@@ -55,7 +57,6 @@ public AttemptInfoRead getAttemptForJob(final GetAttemptStatsRequestBody request
5557
processes = MediaType.APPLICATION_JSON)
5658
@ExecuteOn(AirbyteTaskExecutors.IO)
5759
@Secured({ADMIN})
58-
@SecuredWorkspace
5960
public CreateNewAttemptNumberResponse createNewAttemptNumber(final CreateNewAttemptNumberRequest requestBody) {
6061
return ApiHelper
6162
.execute(() -> attemptHandler.createNewAttemptNumber(requestBody.getJobId()));
@@ -65,7 +66,7 @@ public CreateNewAttemptNumberResponse createNewAttemptNumber(final CreateNewAtte
6566
@Post(uri = "/get_combined_stats",
6667
processes = MediaType.APPLICATION_JSON)
6768
@ExecuteOn(AirbyteTaskExecutors.IO)
68-
@Secured({READER})
69+
@Secured({READER, WORKSPACE_READER, ORGANIZATION_READER})
6970
@SecuredWorkspace
7071
public AttemptStats getAttemptCombinedStats(final GetAttemptStatsRequestBody requestBody) {
7172
return ApiHelper

airbyte-server/src/main/java/io/airbyte/server/apis/ConnectionApiController.java

Lines changed: 20 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,11 @@
66

77
import static io.airbyte.commons.auth.AuthRoleConstants.ADMIN;
88
import static io.airbyte.commons.auth.AuthRoleConstants.EDITOR;
9+
import static io.airbyte.commons.auth.AuthRoleConstants.ORGANIZATION_EDITOR;
10+
import static io.airbyte.commons.auth.AuthRoleConstants.ORGANIZATION_READER;
911
import static io.airbyte.commons.auth.AuthRoleConstants.READER;
12+
import static io.airbyte.commons.auth.AuthRoleConstants.WORKSPACE_EDITOR;
13+
import static io.airbyte.commons.auth.AuthRoleConstants.WORKSPACE_READER;
1014

1115
import io.airbyte.api.generated.ConnectionApi;
1216
import io.airbyte.api.model.generated.ActorDefinitionRequestBody;
@@ -76,15 +80,14 @@ public ConnectionApiController(final ConnectionsHandler connectionsHandler,
7680
@Override
7781
@Post(uri = "/auto_disable")
7882
@Secured({ADMIN})
79-
@SecuredWorkspace
8083
@ExecuteOn(AirbyteTaskExecutors.IO)
8184
public InternalOperationResult autoDisableConnection(@Body final ConnectionIdRequestBody connectionIdRequestBody) {
8285
return ApiHelper.execute(() -> connectionsHandler.autoDisableConnection(connectionIdRequestBody.getConnectionId()));
8386
}
8487

8588
@Override
8689
@Post(uri = "/create")
87-
@Secured({EDITOR})
90+
@Secured({EDITOR, WORKSPACE_EDITOR, ORGANIZATION_EDITOR})
8891
@SecuredWorkspace
8992
@ExecuteOn(AirbyteTaskExecutors.SCHEDULER)
9093
public ConnectionRead createConnection(@Body final ConnectionCreate connectionCreate) {
@@ -93,7 +96,7 @@ public ConnectionRead createConnection(@Body final ConnectionCreate connectionCr
9396

9497
@Override
9598
@Post(uri = "/update")
96-
@Secured({EDITOR})
99+
@Secured({EDITOR, WORKSPACE_EDITOR, ORGANIZATION_EDITOR})
97100
@SecuredWorkspace
98101
@ExecuteOn(AirbyteTaskExecutors.IO)
99102
public ConnectionRead updateConnection(@Body final ConnectionUpdate connectionUpdate) {
@@ -102,7 +105,7 @@ public ConnectionRead updateConnection(@Body final ConnectionUpdate connectionUp
102105

103106
@Override
104107
@Post(uri = "/list")
105-
@Secured({READER})
108+
@Secured({READER, WORKSPACE_READER, ORGANIZATION_READER})
106109
@SecuredWorkspace
107110
@ExecuteOn(AirbyteTaskExecutors.IO)
108111
public ConnectionReadList listConnectionsForWorkspace(@Body final WorkspaceIdRequestBody workspaceIdRequestBody) {
@@ -111,7 +114,7 @@ public ConnectionReadList listConnectionsForWorkspace(@Body final WorkspaceIdReq
111114

112115
@SuppressWarnings("LineLength")
113116
@Post(uri = "/list_paginated")
114-
@Secured({READER})
117+
@Secured({READER, WORKSPACE_READER, ORGANIZATION_READER})
115118
@SecuredWorkspace
116119
@ExecuteOn(AirbyteTaskExecutors.IO)
117120
@Override
@@ -122,7 +125,7 @@ public ConnectionReadList listConnectionsForWorkspacesPaginated(
122125

123126
@Override
124127
@Post(uri = "/list_all")
125-
@Secured({READER})
128+
@Secured({READER, WORKSPACE_READER, ORGANIZATION_READER})
126129
@SecuredWorkspace
127130
@ExecuteOn(AirbyteTaskExecutors.IO)
128131
public ConnectionReadList listAllConnectionsForWorkspace(@Body final WorkspaceIdRequestBody workspaceIdRequestBody) {
@@ -145,7 +148,7 @@ public ConnectionReadList searchConnections(@Body final ConnectionSearch connect
145148

146149
@Override
147150
@Post(uri = "/get")
148-
@Secured({READER})
151+
@Secured({READER, WORKSPACE_READER, ORGANIZATION_READER})
149152
@SecuredWorkspace
150153
@ExecuteOn(AirbyteTaskExecutors.IO)
151154
public ConnectionRead getConnection(@Body final ConnectionIdRequestBody connectionIdRequestBody) {
@@ -154,7 +157,7 @@ public ConnectionRead getConnection(@Body final ConnectionIdRequestBody connecti
154157

155158
@Override
156159
@Post(uri = "/history/data")
157-
@Secured({READER})
160+
@Secured({READER, WORKSPACE_READER, ORGANIZATION_READER})
158161
@SecuredWorkspace
159162
@ExecuteOn(AirbyteTaskExecutors.IO)
160163
public List<ConnectionDataHistoryReadItem> getConnectionDataHistory(ConnectionDataHistoryRequestBody connectionDataHistoryRequestBody) {
@@ -163,7 +166,7 @@ public List<ConnectionDataHistoryReadItem> getConnectionDataHistory(ConnectionDa
163166

164167
@Override
165168
@Post(uri = "/connections/status")
166-
@Secured({READER})
169+
@Secured({READER, WORKSPACE_READER, ORGANIZATION_READER})
167170
@SecuredWorkspace
168171
@ExecuteOn(AirbyteTaskExecutors.IO)
169172
public List<ConnectionStatusRead> getConnectionStatuses(@Body final ConnectionStatusesRequestBody connectionStatusesRequestBody) {
@@ -172,7 +175,7 @@ public List<ConnectionStatusRead> getConnectionStatuses(@Body final ConnectionSt
172175

173176
@Override
174177
@Post(uri = "/stream_history")
175-
@Secured({READER})
178+
@Secured({READER, WORKSPACE_READER, ORGANIZATION_READER})
176179
@SecuredWorkspace
177180
@ExecuteOn(AirbyteTaskExecutors.IO)
178181
public List<ConnectionStreamHistoryReadItem> getConnectionStreamHistory(ConnectionStreamHistoryRequestBody connectionStreamHistoryRequestBody) {
@@ -181,7 +184,7 @@ public List<ConnectionStreamHistoryReadItem> getConnectionStreamHistory(Connecti
181184

182185
@Override
183186
@Post(uri = "/sync_progress")
184-
@Secured({READER})
187+
@Secured({READER, WORKSPACE_READER, ORGANIZATION_READER})
185188
@SecuredWorkspace
186189
@ExecuteOn(AirbyteTaskExecutors.IO)
187190
public List<ConnectionSyncProgressReadItem> getConnectionSyncProgress(ConnectionIdRequestBody connectionIdRequestBody) {
@@ -190,7 +193,7 @@ public List<ConnectionSyncProgressReadItem> getConnectionSyncProgress(Connection
190193

191194
@Override
192195
@Post(uri = "/history/uptime")
193-
@Secured({READER})
196+
@Secured({READER, WORKSPACE_READER, ORGANIZATION_READER})
194197
@SecuredWorkspace
195198
@ExecuteOn(AirbyteTaskExecutors.IO)
196199
public List<ConnectionSyncResultRead> getConnectionUptimeHistory(ConnectionUptimeHistoryRequestBody connectionUptimeHistoryRequestBody) {
@@ -200,7 +203,7 @@ public List<ConnectionSyncResultRead> getConnectionUptimeHistory(ConnectionUptim
200203
@Override
201204
@Post(uri = "/delete")
202205
@Status(HttpStatus.NO_CONTENT)
203-
@Secured({EDITOR})
206+
@Secured({EDITOR, WORKSPACE_EDITOR, ORGANIZATION_EDITOR})
204207
@SecuredWorkspace
205208
@ExecuteOn(AirbyteTaskExecutors.IO)
206209
public void deleteConnection(@Body final ConnectionIdRequestBody connectionIdRequestBody) {
@@ -213,7 +216,7 @@ public void deleteConnection(@Body final ConnectionIdRequestBody connectionIdReq
213216

214217
@Override
215218
@Post(uri = "/sync")
216-
@Secured({EDITOR})
219+
@Secured({EDITOR, WORKSPACE_EDITOR, ORGANIZATION_EDITOR})
217220
@SecuredWorkspace
218221
@ExecuteOn(AirbyteTaskExecutors.SCHEDULER)
219222
public JobInfoRead syncConnection(@Body final ConnectionIdRequestBody connectionIdRequestBody) {
@@ -222,7 +225,7 @@ public JobInfoRead syncConnection(@Body final ConnectionIdRequestBody connection
222225

223226
@Override
224227
@Post(uri = "/reset")
225-
@Secured({EDITOR})
228+
@Secured({EDITOR, WORKSPACE_EDITOR, ORGANIZATION_EDITOR})
226229
@SecuredWorkspace
227230
@ExecuteOn(AirbyteTaskExecutors.SCHEDULER)
228231
public JobInfoRead resetConnection(@Body final ConnectionIdRequestBody connectionIdRequestBody) {
@@ -231,7 +234,7 @@ public JobInfoRead resetConnection(@Body final ConnectionIdRequestBody connectio
231234

232235
@Override
233236
@Post(uri = "/reset/stream")
234-
@Secured({EDITOR})
237+
@Secured({EDITOR, WORKSPACE_EDITOR, ORGANIZATION_EDITOR})
235238
@SecuredWorkspace
236239
@ExecuteOn(AirbyteTaskExecutors.SCHEDULER)
237240
public JobInfoRead resetConnectionStream(final ConnectionStreamRequestBody connectionStreamRequestBody) {
@@ -240,7 +243,7 @@ public JobInfoRead resetConnectionStream(final ConnectionStreamRequestBody conne
240243

241244
@Override
242245
@Post(uri = "/apply_schema_change")
243-
@Secured({EDITOR})
246+
@Secured({EDITOR, WORKSPACE_EDITOR, ORGANIZATION_EDITOR})
244247
@SecuredWorkspace
245248
@ExecuteOn(AirbyteTaskExecutors.IO)
246249
public ConnectionAutoPropagateResult applySchemaChangeForConnection(final ConnectionAutoPropagateSchemaChange request) {
@@ -250,7 +253,6 @@ public ConnectionAutoPropagateResult applySchemaChangeForConnection(final Connec
250253
@Override
251254
@Post(uri = "/get_task_queue_name")
252255
@Secured({ADMIN})
253-
@SecuredWorkspace
254256
@ExecuteOn(AirbyteTaskExecutors.IO)
255257
public TaskQueueNameRead getTaskQueueName(final GetTaskQueueNameRequest request) {
256258
final TemporalJobType jobType;

airbyte-server/src/main/java/io/airbyte/server/apis/ConnectorBuilderProjectApiController.java

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
package io.airbyte.server.apis;
66

77
import static io.airbyte.commons.auth.AuthRoleConstants.EDITOR;
8+
import static io.airbyte.commons.auth.AuthRoleConstants.ORGANIZATION_EDITOR;
9+
import static io.airbyte.commons.auth.AuthRoleConstants.WORKSPACE_EDITOR;
810

911
import io.airbyte.api.generated.ConnectorBuilderProjectApi;
1012
import io.airbyte.api.model.generated.ConnectorBuilderProjectIdWithWorkspaceId;
@@ -41,7 +43,7 @@ public ConnectorBuilderProjectApiController(final ConnectorBuilderProjectsHandle
4143
@Override
4244
@Post(uri = "/create")
4345
@Status(HttpStatus.CREATED)
44-
@Secured({EDITOR})
46+
@Secured({EDITOR, WORKSPACE_EDITOR, ORGANIZATION_EDITOR})
4547
@SecuredWorkspace
4648
@ExecuteOn(AirbyteTaskExecutors.IO)
4749
public ConnectorBuilderProjectIdWithWorkspaceId createConnectorBuilderProject(
@@ -52,7 +54,7 @@ public ConnectorBuilderProjectIdWithWorkspaceId createConnectorBuilderProject(
5254
@Override
5355
@Post(uri = "/delete")
5456
@Status(HttpStatus.NO_CONTENT)
55-
@Secured({EDITOR})
57+
@Secured({EDITOR, WORKSPACE_EDITOR, ORGANIZATION_EDITOR})
5658
@SecuredWorkspace
5759
@ExecuteOn(AirbyteTaskExecutors.IO)
5860
public void deleteConnectorBuilderProject(final ConnectorBuilderProjectIdWithWorkspaceId connectorBuilderProjectIdWithWorkspaceId) {
@@ -65,7 +67,7 @@ public void deleteConnectorBuilderProject(final ConnectorBuilderProjectIdWithWor
6567
@Override
6668
@Post(uri = "/get_with_manifest")
6769
@Status(HttpStatus.OK)
68-
@Secured({EDITOR})
70+
@Secured({EDITOR, WORKSPACE_EDITOR, ORGANIZATION_EDITOR})
6971
@SecuredWorkspace
7072
@ExecuteOn(AirbyteTaskExecutors.IO)
7173
public ConnectorBuilderProjectRead getConnectorBuilderProject(
@@ -76,7 +78,7 @@ public ConnectorBuilderProjectRead getConnectorBuilderProject(
7678
@Override
7779
@Post(uri = "/list")
7880
@Status(HttpStatus.OK)
79-
@Secured({EDITOR})
81+
@Secured({EDITOR, WORKSPACE_EDITOR, ORGANIZATION_EDITOR})
8082
@SecuredWorkspace
8183
@ExecuteOn(AirbyteTaskExecutors.IO)
8284
public ConnectorBuilderProjectReadList listConnectorBuilderProjects(final WorkspaceIdRequestBody workspaceIdRequestBody) {
@@ -86,7 +88,7 @@ public ConnectorBuilderProjectReadList listConnectorBuilderProjects(final Worksp
8688
@Override
8789
@Post(uri = "/publish")
8890
@Status(HttpStatus.OK)
89-
@Secured({EDITOR})
91+
@Secured({EDITOR, WORKSPACE_EDITOR, ORGANIZATION_EDITOR})
9092
@SecuredWorkspace
9193
public SourceDefinitionIdBody publishConnectorBuilderProject(final ConnectorBuilderPublishRequestBody connectorBuilderPublishRequestBody) {
9294
return ApiHelper.execute(() -> connectorBuilderProjectsHandler.publishConnectorBuilderProject(connectorBuilderPublishRequestBody));
@@ -95,7 +97,7 @@ public SourceDefinitionIdBody publishConnectorBuilderProject(final ConnectorBuil
9597
@Override
9698
@Post(uri = "/update")
9799
@Status(HttpStatus.NO_CONTENT)
98-
@Secured({EDITOR})
100+
@Secured({EDITOR, WORKSPACE_EDITOR, ORGANIZATION_EDITOR})
99101
@SecuredWorkspace
100102
@ExecuteOn(AirbyteTaskExecutors.IO)
101103
public void updateConnectorBuilderProject(final ExistingConnectorBuilderProjectWithWorkspaceId existingConnectorBuilderProjectWithWorkspaceId) {

airbyte-server/src/main/java/io/airbyte/server/apis/ConnectorDocumentationApiController.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@
44

55
package io.airbyte.server.apis;
66

7+
import static io.airbyte.commons.auth.AuthRoleConstants.ORGANIZATION_READER;
78
import static io.airbyte.commons.auth.AuthRoleConstants.READER;
9+
import static io.airbyte.commons.auth.AuthRoleConstants.WORKSPACE_READER;
810

911
import io.airbyte.api.generated.ConnectorDocumentationApi;
1012
import io.airbyte.api.model.generated.ConnectorDocumentationRead;
@@ -36,7 +38,7 @@ public ConnectorDocumentationApiController(final ConnectorDocumentationHandler c
3638
@Override
3739
@Post(uri = "/get")
3840
@Status(HttpStatus.OK)
39-
@Secured({READER})
41+
@Secured({READER, WORKSPACE_READER, ORGANIZATION_READER})
4042
@SecuredWorkspace
4143
@ExecuteOn(AirbyteTaskExecutors.IO)
4244
public ConnectorDocumentationRead getConnectorDocumentation(ConnectorDocumentationRequestBody connectorDocumentationRequestBody) {

airbyte-server/src/main/java/io/airbyte/server/apis/DeclarativeSourceDefinitionsApiController.java

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
package io.airbyte.server.apis;
66

77
import static io.airbyte.commons.auth.AuthRoleConstants.EDITOR;
8+
import static io.airbyte.commons.auth.AuthRoleConstants.ORGANIZATION_EDITOR;
9+
import static io.airbyte.commons.auth.AuthRoleConstants.WORKSPACE_EDITOR;
810

911
import io.airbyte.api.generated.DeclarativeSourceDefinitionsApi;
1012
import io.airbyte.api.model.generated.DeclarativeManifestsReadList;
@@ -37,7 +39,7 @@ public DeclarativeSourceDefinitionsApiController(final DeclarativeSourceDefiniti
3739
@Override
3840
@Post(uri = "/create_manifest")
3941
@Status(HttpStatus.CREATED)
40-
@Secured({EDITOR})
42+
@Secured({EDITOR, WORKSPACE_EDITOR, ORGANIZATION_EDITOR})
4143
@SecuredWorkspace
4244
@ExecuteOn(AirbyteTaskExecutors.IO)
4345
public void createDeclarativeSourceDefinitionManifest(final DeclarativeSourceDefinitionCreateManifestRequestBody requestBody) {
@@ -50,7 +52,7 @@ public void createDeclarativeSourceDefinitionManifest(final DeclarativeSourceDef
5052
@Override
5153
@Post(uri = "/update_active_manifest")
5254
@Status(HttpStatus.NO_CONTENT)
53-
@Secured({EDITOR})
55+
@Secured({EDITOR, WORKSPACE_EDITOR, ORGANIZATION_EDITOR})
5456
@SecuredWorkspace
5557
@ExecuteOn(AirbyteTaskExecutors.IO)
5658
public void updateDeclarativeManifestVersion(UpdateActiveManifestRequestBody requestBody) {
@@ -63,7 +65,7 @@ public void updateDeclarativeManifestVersion(UpdateActiveManifestRequestBody req
6365
@Override
6466
@Post(uri = "/list_manifests")
6567
@Status(HttpStatus.OK)
66-
@Secured({EDITOR})
68+
@Secured({EDITOR, WORKSPACE_EDITOR, ORGANIZATION_EDITOR})
6769
@SecuredWorkspace
6870
@ExecuteOn(AirbyteTaskExecutors.IO)
6971
public DeclarativeManifestsReadList listDeclarativeManifests(

0 commit comments

Comments
 (0)