Skip to content

Commit 50759fb

Browse files
out_azure_kusto: Added workload identity support (#10283)
--------- Signed-off-by: Tanmaya Panda <[email protected]>
1 parent 459d4a1 commit 50759fb

File tree

6 files changed

+427
-61
lines changed

6 files changed

+427
-61
lines changed

plugins/out_azure_kusto/azure_kusto.c

Lines changed: 41 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -52,12 +52,27 @@ static int azure_kusto_get_msi_token(struct flb_azure_kusto *ctx)
5252
return 0;
5353
}
5454

55-
/* Create a new oauth2 context and get a oauth2 token */
56-
static int azure_kusto_get_oauth2_token(struct flb_azure_kusto *ctx)
55+
static int azure_kusto_get_workload_identity_token(struct flb_azure_kusto *ctx)
5756
{
5857
int ret;
59-
char *token;
58+
59+
ret = flb_azure_workload_identity_token_get(ctx->o,
60+
ctx->workload_identity_token_file,
61+
ctx->client_id,
62+
ctx->tenant_id);
63+
if (ret == -1) {
64+
flb_plg_error(ctx->ins, "error retrieving workload identity token");
65+
return -1;
66+
}
67+
68+
flb_plg_debug(ctx->ins, "Workload identity token retrieved successfully");
69+
return 0;
70+
}
6071

72+
static int azure_kusto_get_service_principal_token(struct flb_azure_kusto *ctx)
73+
{
74+
int ret;
75+
6176
/* Clear any previous oauth2 payload content */
6277
flb_oauth2_payload_clear(ctx->o);
6378

@@ -86,7 +101,7 @@ static int azure_kusto_get_oauth2_token(struct flb_azure_kusto *ctx)
86101
}
87102

88103
/* Retrieve access token */
89-
token = flb_oauth2_token_get(ctx->o);
104+
char *token = flb_oauth2_token_get(ctx->o);
90105
if (!token) {
91106
flb_plg_error(ctx->ins, "error retrieving oauth2 access token");
92107
return -1;
@@ -107,11 +122,18 @@ flb_sds_t get_azure_kusto_token(struct flb_azure_kusto *ctx)
107122
}
108123

109124
if (flb_oauth2_token_expired(ctx->o) == FLB_TRUE) {
110-
if (ctx->managed_identity_client_id != NULL) {
111-
ret = azure_kusto_get_msi_token(ctx);
112-
}
113-
else {
114-
ret = azure_kusto_get_oauth2_token(ctx);
125+
switch (ctx->auth_type) {
126+
case FLB_AZURE_KUSTO_AUTH_WORKLOAD_IDENTITY:
127+
ret = azure_kusto_get_workload_identity_token(ctx);
128+
break;
129+
case FLB_AZURE_KUSTO_AUTH_MANAGED_IDENTITY_SYSTEM:
130+
case FLB_AZURE_KUSTO_AUTH_MANAGED_IDENTITY_USER:
131+
ret = azure_kusto_get_msi_token(ctx);
132+
break;
133+
case FLB_AZURE_KUSTO_AUTH_SERVICE_PRINCIPAL:
134+
default:
135+
ret = azure_kusto_get_service_principal_token(ctx);
136+
break;
115137
}
116138
}
117139

@@ -205,7 +227,7 @@ flb_sds_t execute_ingest_csl_command(struct flb_azure_kusto *ctx, const char *cs
205227
ctx->ins,
206228
"Kusto ingestion command request http_do=%i, HTTP Status: %i",
207229
ret, c->resp.status);
208-
flb_plg_debug(ctx->ins, "Kusto ingestion command HTTP request payload: %.*s", (int)c->resp.payload_size, c->resp.payload);
230+
flb_plg_debug(ctx->ins, "Kusto ingestion command HTTP response payload: %.*s", (int)c->resp.payload_size, c->resp.payload);
209231

210232
if (ret == 0) {
211233
if (c->resp.status == 200) {
@@ -1413,7 +1435,7 @@ static void cb_azure_kusto_flush(struct flb_event_chunk *event_chunk,
14131435
/* Error handling and cleanup */
14141436
if (json) {
14151437
flb_sds_destroy(json);
1416-
}
1438+
}
14171439
if (is_compressed && final_payload) {
14181440
flb_free(final_payload);
14191441
}
@@ -1494,16 +1516,18 @@ static struct flb_config_map config_map[] = {
14941516
"Set the tenant ID of the AAD application used for authentication"},
14951517
{FLB_CONFIG_MAP_STR, "client_id", (char *)NULL, 0, FLB_TRUE,
14961518
offsetof(struct flb_azure_kusto, client_id),
1497-
"Set the client ID (Application ID) of the AAD application used for authentication"},
1519+
"Set the client ID (Application ID) of the AAD application or the user-assigned managed identity's client ID when using managed identity authentication"},
14981520
{FLB_CONFIG_MAP_STR, "client_secret", (char *)NULL, 0, FLB_TRUE,
14991521
offsetof(struct flb_azure_kusto, client_secret),
15001522
"Set the client secret (Application Password) of the AAD application used for "
15011523
"authentication"},
1502-
{FLB_CONFIG_MAP_STR, "managed_identity_client_id", (char *)NULL, 0, FLB_TRUE,
1503-
offsetof(struct flb_azure_kusto, managed_identity_client_id),
1504-
"A managed identity client id to authenticate with. "
1505-
"Set to 'system' for system-assigned managed identity. "
1506-
"Set the MI client ID (GUID) for user-assigned managed identity."},
1524+
{FLB_CONFIG_MAP_STR, "workload_identity_token_file", (char *)NULL, 0, FLB_TRUE,
1525+
offsetof(struct flb_azure_kusto, workload_identity_token_file),
1526+
"Set the token file path for workload identity authentication"},
1527+
{FLB_CONFIG_MAP_STR, "auth_type", "service_principal", 0, FLB_TRUE,
1528+
offsetof(struct flb_azure_kusto, auth_type_str),
1529+
"Set the authentication type: 'service_principal', 'managed_identity', or 'workload_identity'. "
1530+
"For managed_identity, use 'system' as client_id for system-assigned identity, or specify the managed identity's client ID"},
15071531
{FLB_CONFIG_MAP_STR, "ingestion_endpoint", (char *)NULL, 0, FLB_TRUE,
15081532
offsetof(struct flb_azure_kusto, ingestion_endpoint),
15091533
"Set the Kusto cluster's ingestion endpoint URL (e.g. "

plugins/out_azure_kusto/azure_kusto.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,14 @@
3535
/* refresh token every 50 minutes */
3636
#define FLB_AZURE_KUSTO_TOKEN_REFRESH 3000
3737

38+
/* Authentication types */
39+
typedef enum {
40+
FLB_AZURE_KUSTO_AUTH_SERVICE_PRINCIPAL = 0, /* Client ID + Client Secret */
41+
FLB_AZURE_KUSTO_AUTH_MANAGED_IDENTITY_SYSTEM, /* System-assigned managed identity */
42+
FLB_AZURE_KUSTO_AUTH_MANAGED_IDENTITY_USER, /* User-assigned managed identity */
43+
FLB_AZURE_KUSTO_AUTH_WORKLOAD_IDENTITY /* Workload Identity */
44+
} flb_azure_kusto_auth_type;
45+
3846
/* Kusto streaming inserts oauth scope */
3947
#define FLB_AZURE_KUSTO_SCOPE "https://help.kusto.windows.net/.default"
4048

@@ -92,6 +100,11 @@ struct flb_azure_kusto {
92100
int ingestion_endpoint_connect_timeout;
93101
int io_timeout;
94102

103+
/* Authentication */
104+
int auth_type;
105+
char *auth_type_str;
106+
char *workload_identity_token_file;
107+
95108
/* compress payload */
96109
int compression_enabled;
97110

plugins/out_azure_kusto/azure_kusto_conf.c

Lines changed: 63 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -722,8 +722,55 @@ struct flb_azure_kusto *flb_azure_kusto_conf_create(struct flb_output_instance *
722722
return NULL;
723723
}
724724

725-
if (ctx->tenant_id == NULL && ctx->client_id == NULL && ctx->client_secret == NULL && ctx->managed_identity_client_id == NULL) {
726-
flb_plg_error(ctx->ins, "Service Principal or Managed Identity is not defined");
725+
/* Auth method validation and setup */
726+
if (strcasecmp(ctx->auth_type_str, "service_principal") == 0) {
727+
ctx->auth_type = FLB_AZURE_KUSTO_AUTH_SERVICE_PRINCIPAL;
728+
729+
/* Verify required parameters for Service Principal auth */
730+
if (!ctx->tenant_id || !ctx->client_id || !ctx->client_secret) {
731+
flb_plg_error(ins, "When using service_principal auth, tenant_id, client_id, and client_secret are required");
732+
flb_azure_kusto_conf_destroy(ctx);
733+
return NULL;
734+
}
735+
}
736+
else if (strcasecmp(ctx->auth_type_str, "managed_identity") == 0) {
737+
/* Check if client_id indicates system-assigned or user-assigned managed identity */
738+
if (!ctx->client_id) {
739+
flb_plg_error(ins, "When using managed_identity auth, client_id must be set to 'system' for system-assigned or the managed identity client ID");
740+
flb_azure_kusto_conf_destroy(ctx);
741+
return NULL;
742+
}
743+
744+
if (strcasecmp(ctx->client_id, "system") == 0) {
745+
ctx->auth_type = FLB_AZURE_KUSTO_AUTH_MANAGED_IDENTITY_SYSTEM;
746+
} else {
747+
ctx->auth_type = FLB_AZURE_KUSTO_AUTH_MANAGED_IDENTITY_USER;
748+
}
749+
}
750+
else if (strcasecmp(ctx->auth_type_str, "workload_identity") == 0) {
751+
ctx->auth_type = FLB_AZURE_KUSTO_AUTH_WORKLOAD_IDENTITY;
752+
753+
/* Verify required parameters for Workload Identity auth */
754+
if (!ctx->tenant_id || !ctx->client_id) {
755+
flb_plg_error(ins, "When using workload_identity auth, tenant_id and client_id are required");
756+
flb_azure_kusto_conf_destroy(ctx);
757+
return NULL;
758+
}
759+
760+
/* Set default token file path if not specified */
761+
if (!ctx->workload_identity_token_file) {
762+
ctx->workload_identity_token_file = flb_strdup("/var/run/secrets/azure/tokens/azure-identity-token");
763+
if (!ctx->workload_identity_token_file) {
764+
flb_errno();
765+
flb_plg_error(ins, "Could not allocate default workload identity token path");
766+
flb_azure_kusto_conf_destroy(ctx);
767+
return NULL;
768+
}
769+
}
770+
}
771+
else {
772+
flb_plg_error(ins, "Invalid auth_type '%s'. Valid options are: 'service_principal', 'managed_identity', or 'workload_identity'",
773+
ctx->auth_type_str);
727774
flb_azure_kusto_conf_destroy(ctx);
728775
return NULL;
729776
}
@@ -749,60 +796,35 @@ struct flb_azure_kusto *flb_azure_kusto_conf_create(struct flb_output_instance *
749796
return NULL;
750797
}
751798

752-
if (ctx->managed_identity_client_id != NULL) {
753-
/* system assigned managed identity */
754-
if (strcasecmp(ctx->managed_identity_client_id, "system") == 0) {
799+
/* Create oauth2 context */
800+
if (ctx->auth_type == FLB_AZURE_KUSTO_AUTH_MANAGED_IDENTITY_SYSTEM ||
801+
ctx->auth_type == FLB_AZURE_KUSTO_AUTH_MANAGED_IDENTITY_USER) {
802+
/* MSI auth */
803+
/* Construct the URL template with or without client_id for managed identity */
804+
if (ctx->auth_type == FLB_AZURE_KUSTO_AUTH_MANAGED_IDENTITY_SYSTEM) {
755805
ctx->oauth_url = flb_sds_create_size(sizeof(FLB_AZURE_MSIAUTH_URL_TEMPLATE) - 1);
756-
757806
if (!ctx->oauth_url) {
758807
flb_errno();
759808
flb_azure_kusto_conf_destroy(ctx);
760809
return NULL;
761810
}
762-
763811
flb_sds_snprintf(&ctx->oauth_url, flb_sds_alloc(ctx->oauth_url),
764812
FLB_AZURE_MSIAUTH_URL_TEMPLATE, "", "");
765-
766-
}
767-
else {
768-
/* user assigned managed identity */
813+
} else {
814+
/* User-assigned managed identity */
769815
ctx->oauth_url = flb_sds_create_size(sizeof(FLB_AZURE_MSIAUTH_URL_TEMPLATE) - 1 +
770-
sizeof("&client_id=") - 1 +
771-
flb_sds_len(ctx->managed_identity_client_id));
772-
816+
sizeof("&client_id=") - 1 +
817+
flb_sds_len(ctx->client_id));
773818
if (!ctx->oauth_url) {
774819
flb_errno();
775820
flb_azure_kusto_conf_destroy(ctx);
776821
return NULL;
777822
}
778-
779823
flb_sds_snprintf(&ctx->oauth_url, flb_sds_alloc(ctx->oauth_url),
780-
FLB_AZURE_MSIAUTH_URL_TEMPLATE, "&client_id=", ctx->managed_identity_client_id);
781-
}
782-
}
783-
else {
784-
/* config: 'tenant_id' */
785-
if (ctx->tenant_id == NULL) {
786-
flb_plg_error(ctx->ins, "property 'tenant_id' is not defined.");
787-
flb_azure_kusto_conf_destroy(ctx);
788-
return NULL;
824+
FLB_AZURE_MSIAUTH_URL_TEMPLATE, "&client_id=", ctx->client_id);
789825
}
790-
791-
/* config: 'client_id' */
792-
if (ctx->client_id == NULL) {
793-
flb_plg_error(ctx->ins, "property 'client_id' is not defined");
794-
flb_azure_kusto_conf_destroy(ctx);
795-
return NULL;
796-
}
797-
798-
/* config: 'client_secret' */
799-
if (ctx->client_secret == NULL) {
800-
flb_plg_error(ctx->ins, "property 'client_secret' is not defined");
801-
flb_azure_kusto_conf_destroy(ctx);
802-
return NULL;
803-
}
804-
805-
/* Create the auth URL */
826+
} else {
827+
/* Standard OAuth2 for service principal or workload identity */
806828
ctx->oauth_url = flb_sds_create_size(sizeof(FLB_MSAL_AUTH_URL_TEMPLATE) - 1 +
807829
flb_sds_len(ctx->tenant_id));
808830
if (!ctx->oauth_url) {
@@ -811,10 +833,9 @@ struct flb_azure_kusto *flb_azure_kusto_conf_create(struct flb_output_instance *
811833
return NULL;
812834
}
813835
flb_sds_snprintf(&ctx->oauth_url, flb_sds_alloc(ctx->oauth_url),
814-
FLB_MSAL_AUTH_URL_TEMPLATE, ctx->tenant_id);
836+
FLB_MSAL_AUTH_URL_TEMPLATE, ctx->tenant_id);
815837
}
816838

817-
818839
ctx->resources = flb_calloc(1, sizeof(struct flb_azure_kusto_resources));
819840
if (!ctx->resources) {
820841
flb_errno();

0 commit comments

Comments
 (0)