Add SNS as a event listener to the s3 without adding additional policy - aws-cdk

I have an SNS which will listen to multiple S3 buckets. SNS is having the access policy like below.
{
"Sid": "0",
"Effect": "Allow",
"Principal": {
"Service": "s3.amazonaws.com"
},
"Action": "sns:Publish",
"Resource": "arn:aws:sns:us-east-1:XXXXXXXXXXX:dummy-topic-name",
"Condition": {
"StringEquals": {
"AWS:SourceAccount": "XXXXXXXXXXX"
}
}
}
This permission will allow all s3 buckets to send notification to the SQS. Currently, I'm adding SNS to S3 buckets event settings like below.
bucketList.forEach(bucket => bucket.addEventNotification(EventType.OBJECT_CREATED, new SnsDestination(snsTopic)));
This one works well, but it adds additional policy to the SNS access policy, like below.
{
"Sid": "2",
"Effect": "Allow",
"Principal": {
"Service": "s3.amazonaws.com"
},
"Action": "sns:Publish",
"Resource": "arn:aws:sns:us-east-1:XXXXXXXXXXX:dummy-topic-name",
"Condition": {
"ArnLike": {
"aws:SourceArn": "arn:aws:s3:::dummy-s3-bucket"
}
}
}
I have lots of buckets (in the 100's) sending notifications to the same SNS. Now, 100 policies like above will hit the SNS access policy size limit.
Is there a way to add SNS to the S3 event notification without updating the SNS access policy using CDK?

TL;DR Replace the CDK-generated AWS::SNS::TopicPolicy with a manually defined one.
As you say, bucket.addEventNotification adds a bucket-specific statement to the topic's resource policy resource (AWS::SNS::TopicPolicy). Use escape hatch syntax to delete the generated AWS::SNS::TopicPolicy. Add a new one by hand:
Identify the generated CfnTopicPolicy's CDK construct id.
const childIds = topic.node.children.map((c) => c.node.id);
console.log(childIds); // -> [ 'Resource', 'Policy' ]
Looks like the construct id is "Policy". Remove it.
const success = topic.node.tryRemoveChild('Policy');
if (!success) throw new Error('Could not remove the Topic Policy!');
Add the desired policy manually.
new sns.TopicPolicy(this, 'TopicPolicy', {
topics: [topic],
policyDocument: new iam.PolicyDocument({
statements: [
new iam.PolicyStatement({
actions: ['sns:Publish'],
principals: [new iam.ServicePrincipal('s3.amazonaws.com')],
conditions: { StringEquals: { 'AWS:SourceAccount': this.account } },
resources: [topic.topicArn],
}),
],
}),
});

Related

Why we have to pass clients array to modifyGroup command in dynamic security plugin?

In mosquitto docs, we have to pass both roles and clients whenever we are updating a group. When we pass it, the client belongs to group, but the client object is not updated and the group where it was attached is not listened on GetGroup command.
I thought there is a hierarchy of Mqtt Entities (Clients->Groups->Roles) and lower level entities cannot contain higher level entities, but groups somehow can.
Why we have to pass clients array to modifyGroup command?
Only the entries that are present in the modifyGroup object are modified. So if you send:
{
"commands":[{
"command": "modifyGroup",
"groupname": "mygroup",
"clients": [ { "username": "client", "priority": 1 } ]
}]
}
Then mygroup will be modified to have a single user client.
If instead you send:
{
"commands":[{
"command": "modifyGroup",
"groupname": "mygroup",
"clients": []
}]
}
Then mygroup will be modified to have no clients.
Finally, if you send:
{
"commands":[{
"command": "modifyGroup",
"groupname": "mygroup",
"textdescription": "text"
}]
}
Then the group members will not be modified.
If you don't have this behaviour, please update your question with examples of exactly what you are sending that produces an error.
Both roles and clients are marked as optional in the example for modifying a group
Modify Group
Command:
{
"commands":[
{
"command": "modifyGroup",
"groupname": "group to modify",
"textname": "", # Optional
"textdescription": "", # Optional
"roles": [
{ "rolename": "role", "priority": 1 }
], # Optional
"clients": [
{ "username": "client", "priority": 1 }
] # Optional
}
]
}

OPA policy where if kustomize.toolkit.fluxcd.io/reconcile: disabled label is present in helm release yaml it should display a message

is their any OPA policy example where i can design a OPA policy like if specific label is present than it should display the message or warning
i mean i want to design an OPA policy where if kustomize.toolkit.fluxcd.io/reconcile: disabled label is present in helm release yaml it should display a message/warning that kustomize disabled label is there in helm release
can anyone please help me
It’s possible to return warning messages to clients from an admission webhook. The format is documented here.
{
"apiVersion": "admission.k8s.io/v1",
"kind": "AdmissionReview",
"response": {
"uid": "<value from request.uid>",
"allowed": true,
"warnings": [
"duplicate envvar entries specified with name MY_ENV",
"memory request less than 4MB specified for container mycontainer, which will not start successfully"
]
}
}
Let's imagine you have an input object like this:
{
"kind": "AdmissionReview",
"request": {
"kind": {
"kind": "HelmRelease",
"version": "v1"
},
"object": {
"metadata": {
"annotations": {
"kustomize.toolkit.fluxcd.io/reconcile": "disabled"
},
"name": "myapp"
}
}
}
}
Using a policy like this would return warnings to your client when called on the /v0/data API
package play
import future.keywords.contains
import future.keywords.if
warn contains msg if {
input.request.kind == "HelmRelease"
input.request.object.metadata.annotations["kustomize.toolkit.fluxcd.io/reconcile"] == "disabled"
msg := "kustomize disabled"
}
response = {
"apiVersion": "admission.k8s.io/v1",
"kind": "AdmissionReview",
"response": {
"uid": "1234",
"allowed": true,
"warnings": warn,
},
}

Cant create proper OpenID Connect configuration endpoint (v2)

I want to have an application in azure (simple asp.net mvc application) that keeps users in azure, I want to have that done by azure b2c.
I registered application in azure and put all configurations into appsettings.json what I notice is that the url generated by application does not match the one from azure:
Here's from application:
'https://isthereanynewscodeblast.b2clogin.com/isthereanynewscodeblast.onmicrosoft.com/B2C_1_eclaims_login/v2.0/.well-known/openid-configuration'
Here's from B2C:
'https://isthereanynewscodeblast.b2clogin.com/isthereanynewscodeblast.onmicrosoft.com//v2.0/.well-known/openid-configuration'
Similar but not the same. What I have found is that the url is being generated by AzureADB2COpenIdConnectOptionsConfiguration in this method:
internal static string BuildAuthority(AzureADB2COptions AzureADB2COptions)
{
var baseUri = new Uri(AzureADB2COptions.Instance);
var pathBase = baseUri.PathAndQuery.TrimEnd('/');
var domain = AzureADB2COptions.Domain;
var policy = AzureADB2COptions.DefaultPolicy;
return new Uri(baseUri, new PathString($"{pathBase}/{domain}/{policy}/v2.0")).ToString();
}
And here's my .json
"AzureAdB2C": {
"Instance": "https://isthereanynewscodeblast.b2clogin.com",
"Domain": "isthereanynewscodeblast.onmicrosoft.com",
"ClientId": "guid-of-client",
"CallbackPath": "/signin-oidc",
"SignUpSignInPolicyId": "B2C_1_eclaims_login ",
"ResetPasswordPolicyId": "B2C_1_eclaims_reset",
"EditProfilePolicyId": "B2C_1_eclaims_edit"
},
Which does not match the one from AAD :(
Code is from a nuget: Microsoft.AspNetCore.Authorization
It's not protected nor virtual, so I don't see any option to override it.
So my questions are:
is there a way to handle this somehow, so that application can communicate with azure
is there other way to register app, easy like this:
services.AddAuthentication(AzureADB2CDefaults.AuthenticationScheme)
.AddAzureADB2C(options =>
{
Configuration.Bind("AzureAdB2C", options);
});
//EDIT:
Here's manifest from application registration:
{
"id": "438a430b-4e80-4c6c-8f45-dfca460b2e03",
"acceptMappedClaims": null,
"accessTokenAcceptedVersion": 2,
"addIns": [],
"allowPublicClient": null,
"appId": "44234136-6eee-431f-98ea-668343d7a3fd",
"appRoles": [],
"oauth2AllowUrlPathMatching": false,
"createdDateTime": "2020-08-18T22:32:28Z",
"groupMembershipClaims": null,
"identifierUris": [],
"informationalUrls": {
"termsOfService": null,
"support": null,
"privacy": null,
"marketing": null
},
"keyCredentials": [],
"knownClientApplications": [],
"logoUrl": null,
"logoutUrl": null,
"name": "user-log-test",
"oauth2AllowIdTokenImplicitFlow": false,
"oauth2AllowImplicitFlow": false,
"oauth2Permissions": [],
"oauth2RequirePostResponse": false,
"optionalClaims": null,
"orgRestrictions": [],
"parentalControlSettings": {
"countriesBlockedForMinors": [],
"legalAgeGroupRule": "Allow"
},
"passwordCredentials": [],
"preAuthorizedApplications": [],
"publisherDomain": "isthereanynewscodeblast.onmicrosoft.com",
"replyUrlsWithType": [
{
"url": "https://localhost:44395/signin-oidc",
"type": "Web"
}
],
"requiredResourceAccess": [
{
"resourceAppId": "00000003-0000-0000-c000-000000000000",
"resourceAccess": [
{
"id": "37f7f235-527c-4136-accd-4a02d197296e",
"type": "Scope"
},
{
"id": "7427e0e9-2fba-42fe-b0c0-848c9e6a8182",
"type": "Scope"
}
]
}
],
"samlMetadataUrl": null,
"signInUrl": null,
"signInAudience": "AzureADandPersonalMicrosoftAccount",
"tags": [],
"tokenEncryptionKeyId": null
}
Can you please try using this b2c sample app which will give you an idea how to use b2c points. It comes with pre-configured endpoints (below), which you can replace with your tenant and policy later for testing.
{
"AzureAdB2C": {
"Instance": "https://fabrikamb2c.b2clogin.com",
"ClientId": "90c0fe63-bcf2-44d5-8fb7-b8bbc0b29dc6",
"Domain": "fabrikamb2c.onmicrosoft.com",
"SignedOutCallbackPath": "/signout/B2C_1_susi",
"SignUpSignInPolicyId": "b2c_1_susi",
"ResetPasswordPolicyId": "b2c_1_reset",
"EditProfilePolicyId": "b2c_1_edit_profile"
},
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"AllowedHosts": "*"
}
I saw your app manifest file and found that you have not enabled implicit flow. Please Select the app and go to Authentication and select ID Tokens and Access Tokens.
I tried on the sample shared by #Razi and it is working fine end-to-end.

Serverless Lambda SQS access denied error

I have a node application running through serverless-framework.
The application writes messages to the SQS and code is
const AWS = require('aws-sdk');
const config = require('../../configs/constants').config;
const sqs = new AWS.SQS({apiVersion: '2012-11-05'});
module.exports.sendMessage = (service, message) => {
const params = {
MessageBody: JSON.stringify(message),
QueueUrl: config.SQS_QUEUE_URL_ANALYTICS
};
return new Promise((resolve, reject) => {
sqs.sendMessage(params, (err, data) => {
if (err) {
console.error('Error creating SQS Message: ', err);
reject(err);
} else {
console.log('SQS Message created successfully: ', data);
resolve(data);
}
});
});
};
The permission given to the user is
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": [
"sqs:ListQueues",
"sqs:*"
],
"Resource": "*"
},
{
"Sid": "VisualEditor1",
"Effect": "Allow",
"Action": "sqs:*",
"Resource": "arn:aws:sqs:ap-south-1:881210447458:Staging-Analytics-Log-Data-Process"
}
]
}
When the lambda function is executed, it gives an error
ERROR Error creating SQS Message: { AccessDenied: Access to the resource https://sqs.ap-south-1.amazonaws.com/ is denied.
What other credentials are required for SQS to run?
Insert this permission under your provider: tab in serverless.yml:
iamRoleStatements:
- Effect: Allow
Action:
- sqs:SendMessage
Resource: <your swq ARN that starts with (arn:aws:sqs:)>
To send message from AWS Lambda to SQS, you need IM role attached to your Lambda to send messages to SQS. Because in AWS, you need permission for accessing other services resources:
Create IM ROLE with permission for SQS or Required Access
Assign Created IM Role while creating Lambda function at start
See Permission assigned permission for your lambda at Permission tab
Not sure if the wildcard is missing your permissions, but from the code you posted you should only need the permissions to send message.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": [
"sqs:SendMessage"
],
"Resource": "arn:aws:sqs:ap-south-1:881210447458:Staging-Analytics-Log-Data-Process"
}
]
}

How to fix "Unsupported AAD Identity" when create a call from webapp?

When I call this from my web app, I'm getting an error code 9000 - "Unsupported AAD Identity".
POST https://graph.microsoft.com/beta/app/calls
request header:
{
"Content-type" => "application/json",
"Authorization" => "Bearer eyJ0eXAiOiJKV1QiLCJub25jZSI6IkFRQUJBQUFBQUFBUDB3TGxxZExWVG9PcEE0a3d6U254TkY3UDFxM05tT0xEOHZJVXk0NmFtVWRaV1ZhbGdFUWx2Vkw4Mmp4cS1tZFpwOWdiY1kwdVB4U3ctOGlGd3JRM00zUWlBS29KS08zRzN3czNsNlFmZXlBQSIsImFsZyI6IlJTMjU2IiwieDV0IjoidTRPZk5GUEh3RUJvc0hqdHJhdU9iVjg0TG5ZIiwia2lkIjoidTRPZk5GUEh3RUJvc0hqdHJhdU9iVjg0TG5ZIn0.eyJhdWQiOiJodHRwczovL2dyYXBoLm1pY3Jvc29mdC5jb20iLCJpc3MiOiJodHRwczovL3N0cy53aW5kb3dzLm5ldC81NGRkYWJiMS1kNjU5LTRhZmYtODNkZi1kYzUwODk2OTI3YjgvIiwiaWF0IjoxNTYzODQxMTQ2LCJuYmYiOjE1NjM4NDExNDYsImV4cCI6MTU2Mzg0NTA0NiwiYWNjdCI6MCwiYWNyIjoiMSIsImFpbyI6IkFTUUEyLzhNQUFBQWlhS2hob3hBalByVHJsOEZVc0w0Q2Y2Zkc4M2x4YVpIWXVYOTJaT0w5eDQ9IiwiYW1yIjpbInB3ZCIsInJzYSJdLCJhcHBfZGlzcGxheW5hbWUiOiJNeSBSdWJ5IEFwcCIsImFwcGlkIjoiYTFlMjliY2YtODYxOS00ZjVjLWEzMjAtNmY2N2QzMGZiOTlkIiwiYXBwaWRhY3IiOiIxIiwiZGV2aWNlaWQiOiJjMThiZDJmYS05YzhkLTRlOGItYTUwMi1lYWFlMmI2YzM1NjYiLCJmYW1pbHlfbmFtZSI6IuWFqOS9kyIsImdpdmVuX25hbWUiOiLnrqHnkIbogIUiLCJpcGFkZHIiOiIxNTMuMTU2Ljg5LjYzIiwibmFtZSI6IuWFqOS9kyDnrqHnkIbogIUiLCJvaWQiOiIwZGFmMzVhNS1jZjUyLTQ0ODMtYmM0NS0xM2ExYTBlYWE5Y2MiLCJwbGF0ZiI6IjMiLCJwdWlkIjoiMTAwMzIwMDA0OTE0QkVDMCIsInNjcCI6IkNhbGVuZGFycy5SZWFkIERpcmVjdG9yeS5BY2Nlc3NBc1VzZXIuQWxsIERpcmVjdG9yeS5SZWFkLkFsbCBlbWFpbCBHcm91cC5SZWFkLkFsbCBHcm91cC5SZWFkV3JpdGUuQWxsIG9wZW5pZCBwcm9maWxlIFVzZXIuUmVhZCBVc2VyLlJlYWQuQWxsIFVzZXIuUmVhZEJhc2ljLkFsbCIsInNpZ25pbl9zdGF0ZSI6WyJrbXNpIl0sInN1YiI6IktIZ3dXcEdHMWRRdHlUSGplU3pfQ1RPWk03b0w1bHRocWFUclRSbi1ucm8iLCJ0aWQiOiI1NGRkYWJiMS1kNjU5LTRhZmYtODNkZi1kYzUwODk2OTI3YjgiLCJ1bmlxdWVfbmFtZSI6ImFkbWluQGV4ZW9kZXYuaXRlZS5jby5qcCIsInVwbiI6ImFkbWluQGV4ZW9kZXYuaXRlZS5jby5qcCIsInV0aSI6IlVPRURPdnAzWEVTUU9rckU0dEFFQUEiLCJ2ZXIiOiIxLjAiLCJ3aWRzIjpbIjYyZTkwMzk0LTY5ZjUtNDIzNy05MTkwLTAxMjE3NzE0NWUxMCIsImY3MDkzOGEwLWZjMTAtNDE3Ny05ZTkwLTIxNzhmODc2NTczNyJdLCJ4bXNfc3QiOnsic3ViIjoiS2Mwc1JER3hHZFV5eDR6Qk1ucm9XWDhkNVpBTjVKN1EwSTh5SWZnUUhZZyJ9LCJ4bXNfdGNkdCI6MTU1ODMxNTU3OH0.cQmQLHWUfs8iOOPHf5SmWJYgsjQqLjZq9W5pKZzwRBtiQoOsUHILZkGYKz7_jx0bW-p87Cq6mFzswnoK30smEH6l7VW-gkzrxc2JFuDh-nKvfemTKnI3O_ZjtrEJNp-sWZF5Enm28Mg5Lh4hfBrSiROO8b0gAMytLWx9Qjy3H5x_zzdy34D1B1O8nCFrx217olDzarDCd6KqPtfCqoS00mWqCIwlEvHSi7OCtBV0HaUEl07-hi9hovu-uaHTLRW50fFP9hfoWYOz5qRyidpGNRtR26rUtexlOXtceZKYv5fD_VFNiBdT7d06EiK58UBib08eHjcvNJ6NEhcW0xTOxA"
}
request body:
{
"callbackUri": "https://bot.contoso.com/api/calls",
"mediaConfig": {
"#odata.type": "#microsoft.graph.serviceHostedMediaConfig",
"preFetchMedia": [
{
"uri": "https://cdn.contoso.com/beep.wav",
"resourceId": "1D6DE2D4-CD51-4309-8DAA-70768651088E"
},
{
"uri": "https://cdn.contoso.com/cool.wav",
"resourceId": "1D6DE2D4-CD51-4309-8DAA-70768651088F"
}
]
},
"source": {
"identity": {
"application": {
"id": "RealAppId"
}
},
"languageId": "languageId-value",
"region": "region-value"
},
"subject": "Test Call",
"targets": [
{
"identity": {
"user": {
"id": "RealTargetUserId",
"tenantId": "RealTenantId",
"displayName": "RealName"
}
}
}
],
"tenantId": "tenantId-value"
}
response:
{
"error": {
"code": "UnknownError",
"message": "{
"errorCode": "9000",
"message": "Unsupported AAD Identity.",
"instanceAnnotations": []
}",
"innerError": {
"request-id": "RealRequestId",
"date": "2019-07-23T00:25:12"
}
}
}
I n the request body, RealTargetUserId is an Azure ActiveDirectory UserID with an E1 license provisioned. RealAppId is the registered application id and with Permissions as follows:
Calls.AccessMedia.All
Calls.Initiate.All
Calls.InitiateGroupCall.All
Calls.JoinGroupCall.All
Calls.JoinGroupCallAsGuest.All
According to the documentation, you need one of the following Application scopes to create a call: Calls.JoinGroupCallsasGuest.All, Calls.JoinGroupCalls.All, Calls.Initiate.All, Calls.InitiateGroupCalls.All.
The authentication token you're using, however, is using Delegated scopes. This tells me you're either using OAuth's Authentication Code or Implicit grant flows. Neither of these will work for this operation.
In order to use this endpoint, you'll need to request an App-Only token using the OAuth Client Credentials grant. There are instructions on how to do this in the documentation: Get access without a user.
Also, you're over-requesting permission scopes. For example, there is no need to request User.Read, User.Read.All, and User.ReadBasic.All, you only need User.Read.All to accomplish the same thing. The same goes for Group.Read.All and Group.ReadWrite.All.
To fix issues with "Application is not registered in our store" you need to make sure that you use a Bot Channel Registration instead of just a normal App Registration.
The Bot Channel Registration should also have Microsoft Teams as a registered channel and have calling enabled.
For more information see: https://microsoftgraph.github.io/microsoft-graph-comms-samples/docs/articles/calls/register-calling-bot.html
The final step about adding the bot in teams can be skipped if you only care about API access.

Resources