Skip to content

Commit f40ec12

Browse files
committed
out_azure_blob: add OAuth authentication support
Integrate common Azure authentication module to support: - Managed Identity (system-assigned and user-assigned) - Workload Identity with federated tokens - Service Principal with client credentials This extends the existing shared key and SAS token authentication methods and maintains full backward compatibility. New configuration parameters: - tenant_id: Azure AD tenant ID - client_id: Azure AD client ID or 'system' for system-assigned MI - client_secret: Client secret for service principal auth - workload_identity_token_file: Token file path for workload identity Signed-off-by: Shuang Zhang <zshuang0316@163.com>
1 parent ae76627 commit f40ec12

4 files changed

Lines changed: 283 additions & 16 deletions

File tree

plugins/out_azure_blob/azure_blob.c

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1826,7 +1826,7 @@ static struct flb_config_map config_map[] = {
18261826
{
18271827
FLB_CONFIG_MAP_STR, "auth_type", "key",
18281828
0, FLB_TRUE, offsetof(struct flb_azure_blob, auth_type),
1829-
"Set the auth type: key or sas"
1829+
"Set the auth type: key, sas, service_principal, managed_identity, or workload_identity"
18301830
},
18311831

18321832
{
@@ -1835,6 +1835,31 @@ static struct flb_config_map config_map[] = {
18351835
"Azure Blob SAS token"
18361836
},
18371837

1838+
/* OAuth authentication parameters */
1839+
{
1840+
FLB_CONFIG_MAP_STR, "tenant_id", NULL,
1841+
0, FLB_TRUE, offsetof(struct flb_azure_blob, tenant_id),
1842+
"Azure AD tenant ID (required for service_principal and workload_identity auth)"
1843+
},
1844+
1845+
{
1846+
FLB_CONFIG_MAP_STR, "client_id", NULL,
1847+
0, FLB_TRUE, offsetof(struct flb_azure_blob, client_id),
1848+
"Azure AD client ID / Application ID (required for OAuth-based authentication)"
1849+
},
1850+
1851+
{
1852+
FLB_CONFIG_MAP_STR, "client_secret", NULL,
1853+
0, FLB_TRUE, offsetof(struct flb_azure_blob, client_secret),
1854+
"Azure AD client secret (required for service_principal auth)"
1855+
},
1856+
1857+
{
1858+
FLB_CONFIG_MAP_STR, "workload_identity_token_file", NULL,
1859+
0, FLB_TRUE, offsetof(struct flb_azure_blob, workload_identity_token_file),
1860+
"Path to workload identity token file (for workload_identity auth)"
1861+
},
1862+
18381863
{
18391864
FLB_CONFIG_MAP_STR, "database_file", NULL,
18401865
0, FLB_TRUE, offsetof(struct flb_azure_blob, database_file),

plugins/out_azure_blob/azure_blob.h

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@
2424
#include <fluent-bit/flb_upstream.h>
2525
#include <fluent-bit/flb_sds.h>
2626
#include <fluent-bit/flb_sqldb.h>
27+
#include <fluent-bit/flb_oauth2.h>
28+
#include <fluent-bit/flb_azure_auth.h>
2729

2830
/* Content-Type */
2931
#define AZURE_BLOB_CT "Content-Type"
@@ -48,6 +50,7 @@
4850
#define AZURE_BLOB_APPENDBLOB 0
4951
#define AZURE_BLOB_BLOCKBLOB 1
5052

53+
/* Legacy auth type definitions for backward compatibility */
5154
#define AZURE_BLOB_AUTH_KEY 0
5255
#define AZURE_BLOB_AUTH_SAS 1
5356

@@ -65,6 +68,13 @@ struct flb_azure_blob {
6568
flb_sds_t date_key;
6669
flb_sds_t auth_type;
6770
flb_sds_t sas_token;
71+
72+
/* OAuth authentication fields */
73+
flb_sds_t tenant_id;
74+
flb_sds_t client_id;
75+
flb_sds_t client_secret;
76+
flb_sds_t workload_identity_token_file;
77+
6878
flb_sds_t database_file;
6979
size_t part_size;
7080
time_t upload_parts_timeout;
@@ -112,7 +122,7 @@ struct flb_azure_blob {
112122
* Internal use
113123
*/
114124
int btype; /* blob type */
115-
int atype; /* auth type */
125+
int atype; /* auth type (now uses flb_azure_auth_type enum) */
116126
flb_sds_t real_endpoint;
117127
flb_sds_t base_uri;
118128
flb_sds_t shared_key_prefix;
@@ -121,6 +131,11 @@ struct flb_azure_blob {
121131
unsigned char *decoded_sk; /* decoded shared key */
122132
size_t decoded_sk_size; /* size of decoded shared key */
123133

134+
/* OAuth2 authentication */
135+
flb_sds_t oauth_url;
136+
struct flb_oauth2 *o;
137+
pthread_mutex_t token_mutex;
138+
124139
#ifdef FLB_HAVE_SQLDB
125140
/*
126141
* SQLite by default is not built with multi-threading enabled, and

plugins/out_azure_blob/azure_blob_conf.c

Lines changed: 127 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -590,27 +590,70 @@ struct flb_azure_blob *flb_azure_blob_conf_create(struct flb_output_instance *in
590590
/* Set Auth type */
591591
tmp = (char *) flb_output_get_property("auth_type", ins);
592592
if (!tmp) {
593-
ctx->atype = AZURE_BLOB_AUTH_KEY;
593+
ctx->atype = FLB_AZURE_AUTH_KEY; /* Default to legacy key auth */
594594
}
595595
else {
596596
if (strcasecmp(tmp, "key") == 0) {
597-
ctx->atype = AZURE_BLOB_AUTH_KEY;
597+
ctx->atype = FLB_AZURE_AUTH_KEY;
598598
}
599599
else if (strcasecmp(tmp, "sas") == 0) {
600-
ctx->atype = AZURE_BLOB_AUTH_SAS;
600+
ctx->atype = FLB_AZURE_AUTH_SAS;
601+
}
602+
else if (strcasecmp(tmp, "service_principal") == 0) {
603+
ctx->atype = FLB_AZURE_AUTH_SERVICE_PRINCIPAL;
604+
605+
/* Verify required parameters for Service Principal auth */
606+
if (!ctx->tenant_id || !ctx->client_id || !ctx->client_secret) {
607+
flb_plg_error(ins, "When using service_principal auth, tenant_id, client_id, and client_secret are required");
608+
return NULL;
609+
}
610+
}
611+
else if (strcasecmp(tmp, "managed_identity") == 0) {
612+
/* Check if client_id indicates system-assigned or user-assigned managed identity */
613+
if (!ctx->client_id) {
614+
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");
615+
return NULL;
616+
}
617+
618+
if (strcasecmp(ctx->client_id, "system") == 0) {
619+
ctx->atype = FLB_AZURE_AUTH_MANAGED_IDENTITY_SYSTEM;
620+
} else {
621+
ctx->atype = FLB_AZURE_AUTH_MANAGED_IDENTITY_USER;
622+
}
623+
}
624+
else if (strcasecmp(tmp, "workload_identity") == 0) {
625+
ctx->atype = FLB_AZURE_AUTH_WORKLOAD_IDENTITY;
626+
627+
/* Verify required parameters for Workload Identity auth */
628+
if (!ctx->tenant_id || !ctx->client_id) {
629+
flb_plg_error(ins, "When using workload_identity auth, tenant_id and client_id are required");
630+
return NULL;
631+
}
632+
633+
/* Set default token file path if not specified */
634+
if (!ctx->workload_identity_token_file) {
635+
ctx->workload_identity_token_file = flb_sds_create(FLB_AZURE_WORKLOAD_IDENTITY_TOKEN_FILE);
636+
if (!ctx->workload_identity_token_file) {
637+
flb_errno();
638+
flb_plg_error(ins, "Could not allocate default workload identity token path");
639+
return NULL;
640+
}
641+
}
601642
}
602643
else {
603-
flb_plg_error(ctx->ins, "invalid auth_type value '%s'", tmp);
644+
flb_plg_error(ctx->ins, "invalid auth_type value '%s'. Valid options are: 'key', 'sas', 'service_principal', 'managed_identity', or 'workload_identity'", tmp);
604645
return NULL;
605646
}
606647
}
607-
if (ctx->atype == AZURE_BLOB_AUTH_KEY &&
648+
649+
/* Validate auth-specific requirements */
650+
if (ctx->atype == FLB_AZURE_AUTH_KEY &&
608651
ctx->shared_key == NULL) {
609652
flb_plg_error(ctx->ins, "'shared_key' has not been set");
610653
return NULL;
611654
}
612655

613-
if (ctx->atype == AZURE_BLOB_AUTH_SAS) {
656+
if (ctx->atype == FLB_AZURE_AUTH_SAS) {
614657
if (ctx->sas_token == NULL) {
615658
flb_plg_error(ctx->ins, "'sas_token' has not been set");
616659
return NULL;
@@ -730,6 +773,35 @@ struct flb_azure_blob *flb_azure_blob_conf_create(struct flb_output_instance *in
730773
}
731774
flb_output_upstream_set(ctx->u, ins);
732775

776+
/* Initialize OAuth2 context for OAuth-based authentication methods */
777+
if (ctx->atype == FLB_AZURE_AUTH_SERVICE_PRINCIPAL ||
778+
ctx->atype == FLB_AZURE_AUTH_MANAGED_IDENTITY_SYSTEM ||
779+
ctx->atype == FLB_AZURE_AUTH_MANAGED_IDENTITY_USER ||
780+
ctx->atype == FLB_AZURE_AUTH_WORKLOAD_IDENTITY) {
781+
782+
/* Build OAuth URL based on auth type */
783+
ctx->oauth_url = flb_azure_auth_build_oauth_url(ctx->atype,
784+
ctx->tenant_id,
785+
ctx->client_id,
786+
FLB_AZURE_BLOB_RESOURCE_SCOPE);
787+
if (!ctx->oauth_url) {
788+
flb_plg_error(ctx->ins, "failed to create OAuth URL");
789+
return NULL;
790+
}
791+
792+
/* Create OAuth2 context */
793+
ctx->o = flb_oauth2_create(ctx->config, ctx->oauth_url, 3000);
794+
if (!ctx->o) {
795+
flb_plg_error(ctx->ins, "cannot create oauth2 context");
796+
return NULL;
797+
}
798+
799+
/* Initialize token mutex */
800+
pthread_mutex_init(&ctx->token_mutex, NULL);
801+
802+
flb_plg_info(ctx->ins, "oauth2 context initialized for auth type");
803+
}
804+
733805
/* Compose base uri */
734806
ctx->base_uri = flb_sds_create_size(256);
735807
if (!ctx->base_uri) {
@@ -772,13 +844,40 @@ struct flb_azure_blob *flb_azure_blob_conf_create(struct flb_output_instance *in
772844

773845
pthread_mutex_init(&ctx->file_upload_commit_file_parts, NULL);
774846

775-
flb_plg_info(ctx->ins,
776-
"account_name=%s, container_name=%s, blob_type=%s, emulator_mode=%s, endpoint=%s, auth_type=%s",
777-
ctx->account_name, ctx->container_name,
778-
ctx->btype == AZURE_BLOB_APPENDBLOB ? "appendblob" : "blockblob",
779-
ctx->emulator_mode ? "yes" : "no",
780-
ctx->real_endpoint ? ctx->real_endpoint : "no",
781-
ctx->atype == AZURE_BLOB_AUTH_KEY ? "key" : "sas");
847+
/* Log configuration summary */
848+
{
849+
const char *auth_type_str;
850+
switch (ctx->atype) {
851+
case FLB_AZURE_AUTH_KEY:
852+
auth_type_str = "key";
853+
break;
854+
case FLB_AZURE_AUTH_SAS:
855+
auth_type_str = "sas";
856+
break;
857+
case FLB_AZURE_AUTH_SERVICE_PRINCIPAL:
858+
auth_type_str = "service_principal";
859+
break;
860+
case FLB_AZURE_AUTH_MANAGED_IDENTITY_SYSTEM:
861+
auth_type_str = "managed_identity (system)";
862+
break;
863+
case FLB_AZURE_AUTH_MANAGED_IDENTITY_USER:
864+
auth_type_str = "managed_identity (user)";
865+
break;
866+
case FLB_AZURE_AUTH_WORKLOAD_IDENTITY:
867+
auth_type_str = "workload_identity";
868+
break;
869+
default:
870+
auth_type_str = "unknown";
871+
}
872+
873+
flb_plg_info(ctx->ins,
874+
"account_name=%s, container_name=%s, blob_type=%s, emulator_mode=%s, endpoint=%s, auth_type=%s",
875+
ctx->account_name, ctx->container_name,
876+
ctx->btype == AZURE_BLOB_APPENDBLOB ? "appendblob" : "blockblob",
877+
ctx->emulator_mode ? "yes" : "no",
878+
ctx->real_endpoint ? ctx->real_endpoint : "no",
879+
auth_type_str);
880+
}
782881
return ctx;
783882
}
784883

@@ -826,6 +925,21 @@ void flb_azure_blob_conf_destroy(struct flb_azure_blob *ctx)
826925
flb_upstream_destroy(ctx->u);
827926
}
828927

928+
/* Cleanup OAuth2 resources */
929+
if (ctx->oauth_url) {
930+
flb_sds_destroy(ctx->oauth_url);
931+
}
932+
933+
if (ctx->o) {
934+
flb_oauth2_destroy(ctx->o);
935+
}
936+
937+
if (ctx->atype == FLB_AZURE_AUTH_SERVICE_PRINCIPAL ||
938+
ctx->atype == FLB_AZURE_AUTH_MANAGED_IDENTITY_SYSTEM ||
939+
ctx->atype == FLB_AZURE_AUTH_MANAGED_IDENTITY_USER ||
940+
ctx->atype == FLB_AZURE_AUTH_WORKLOAD_IDENTITY) {
941+
pthread_mutex_destroy(&ctx->token_mutex);
942+
}
829943

830944
azb_db_close(ctx);
831945
flb_free(ctx);

0 commit comments

Comments
 (0)