@@ -31,6 +31,7 @@ pub struct CustomServiceAccount {
31
31
signer : Signer ,
32
32
tokens : RwLock < HashMap < Vec < String > , Arc < Token > > > ,
33
33
subject : Option < String > ,
34
+ audience : Option < String > ,
34
35
}
35
36
36
37
impl CustomServiceAccount {
@@ -59,6 +60,12 @@ impl CustomServiceAccount {
59
60
self
60
61
}
61
62
63
+ /// Set the `Audience` to impersonate a user
64
+ pub fn with_audience ( mut self , audience : String ) -> Self {
65
+ self . audience = Some ( audience) ;
66
+ self
67
+ }
68
+
62
69
fn new ( credentials : ServiceAccountKey , client : HttpClient ) -> Result < Self , Error > {
63
70
debug ! ( project = ?credentials. project_id, email = credentials. client_email, "found credentials" ) ;
64
71
Ok ( Self {
@@ -67,13 +74,19 @@ impl CustomServiceAccount {
67
74
credentials,
68
75
tokens : RwLock :: new ( HashMap :: new ( ) ) ,
69
76
subject : None ,
77
+ audience : None ,
70
78
} )
71
79
}
72
80
73
81
#[ instrument( level = Level :: DEBUG , skip( self ) ) ]
74
82
async fn fetch_token ( & self , scopes : & [ & str ] ) -> Result < Arc < Token > , Error > {
75
- let jwt =
76
- Claims :: new ( & self . credentials , scopes, self . subject . as_deref ( ) ) . to_jwt ( & self . signer ) ?;
83
+ let jwt = Claims :: new (
84
+ & self . credentials ,
85
+ scopes,
86
+ self . subject . as_deref ( ) ,
87
+ self . audience . as_deref ( ) ,
88
+ )
89
+ . to_jwt ( & self . signer ) ?;
77
90
let body = Bytes :: from (
78
91
form_urlencoded:: Serializer :: new ( String :: new ( ) )
79
92
. extend_pairs ( & [ ( "grant_type" , GRANT_TYPE ) , ( "assertion" , jwt. as_str ( ) ) ] )
@@ -156,7 +169,12 @@ pub(crate) struct Claims<'a> {
156
169
}
157
170
158
171
impl < ' a > Claims < ' a > {
159
- pub ( crate ) fn new ( key : & ' a ServiceAccountKey , scopes : & [ & str ] , sub : Option < & ' a str > ) -> Self {
172
+ pub ( crate ) fn new (
173
+ key : & ' a ServiceAccountKey ,
174
+ scopes : & [ & str ] ,
175
+ sub : Option < & ' a str > ,
176
+ aud : Option < & ' a str > ,
177
+ ) -> Self {
160
178
let mut scope = String :: with_capacity ( 16 ) ;
161
179
for ( i, s) in scopes. iter ( ) . enumerate ( ) {
162
180
if i != 0 {
@@ -169,7 +187,7 @@ impl<'a> Claims<'a> {
169
187
let iat = Utc :: now ( ) . timestamp ( ) ;
170
188
Claims {
171
189
iss : & key. client_email ,
172
- aud : & key. token_uri ,
190
+ aud : aud . unwrap_or ( & key. token_uri ) ,
173
191
exp : iat + 3600 - 5 , // Max validity is 1h
174
192
iat,
175
193
sub,
0 commit comments