Hashicorp Vault - Template Policy issues with UI - policy

I am trying to establish a shared secret environment for all users but each user cannot see each others secrets. It is working as expected through the CLI but when I try to test it on the web UI it's stating that the test user does not have the correct permissions. I followed this guide https://learn.hashicorp.com/vault/identity-access-management/policy-templating and https://www.vaultproject.io/docs/concepts/policies.html for references but no matter what I do it is not working correctly on the web UI.
Here is how my policies look like.
path "secret/data/{{identity.entity.name}}/*" {
capabilities = ["create", "update", "read", "delete", "sudo"]
}
path "secret/metadata/{{identity.entity.name}}/*" {
capabilities = ["list", "read", "create", "update", "delete", "sudo"]
}
CLI output:
$ vault kv list secret/user
Keys
----
test
UI output:
Any help or suggestions would be much appreciated, thanks.

try this:
path "secret/data/{{identity.entity.name}}/*" {
capabilities = ["create", "update", "read", "delete", "sudo"]
}
path "secret/metadata/{{identity.entity.name}}/*" {
capabilities = ["list"]
}
path "secret/metadata" {
capabilities = ["list"]
}
The problem is that with your policy you have no access to the folder "secret" but only to the path "secret/data/{{identity.entity.name}}". In the navigation of the UI you need additional access rights for the parent folders.

Related

Strapi 4 - User pemissions plugin policy extension

I'm attempting to migrate from Strapi 3 -> 4
I've managed to restructure my folder structure to get the schema working for all my content types.
However, in v3 I had an extra policy on the user-permissions plugin the verified the users jwt token with auth0.
I took the v3 implementation from these docs.
I'm attempting to get it to apply the same logic in v4 and i'm a bit lost since the new docs don't seem fully up-to-date.
I'm adding a new policy in /src/extensions/users-permissions/strapi-server.js
Taken from the docs here
module.exports = (plugin) => {
plugin.policies["permissions"] = async (ctx) => {
let role;
console.log("IN HERE");
if (ctx.state.user) {
// request is already authenticated in a different way
return true;
}
// ... A bunch more logic
return false
}
return plugin
}
If I run yarn strapi policies:list then my 'permissions' policy is listed.
However, when trying to use that policy anywhere, I don't see my console log to see that it's being applied.
I've tried to specify that policy in the routes setup:
module.exports = {
routes: [
{
method: "GET",
path: "/addition-requests",
handler: "addition-request.find",
},
{
method: "GET",
path: "/addition-requests/:id",
handler: "addition-request.findOne",
},
{
method: "POST",
path: "/addition-requests",
config: {
policies: ["plugin::users-permissions.permissions"],
},
handler: "addition-request.create",
},
],
};
Is there anything obvious I'm missing?
And is there a way to apply a policy to every request that requires auth rather than specifying a policy on the route?
It appears from reading this comment it appears as though any request made to a Strapi endpoint that contains a Bearer token is treated like a request that requires auth.
That seems to be why the policy isn't being run as if I remove the Authorization header the policy does run. The question of how to execute a policy on an endpoint that requires auth still remains however.
It appears that the issue around being able to do custom validation on a users jwt is an issue that a few people are facing with v4 Strapi. See my topic on their forum.

How to add mock data containing authorized owner to Amplify (either through GraphiQL or directly to AppSync)?

I'm working on a React app and testing some CRUD functionality by mocking the backend, creating some data through GraphiQL, and running the app (amplify mock, then yarn start).
I want to be able to create mock data tied to my user as the owner because most types in the schema are set up with owner authorization:
type XYZ
#auth(rules: [{ allow: owner, operations: [update, delete, create] }]) {
id: ID!
...more types...etc
}
Right now, I
run amplify mock
Go to GraphiQL local endpoint (192.etc....)
Run some createXYZ mutations to create data
Run my app w yarn start
login with testUser & password
Test the deleteXYZ button which should ideally remove a particular XYZ from the mocked data this is what doesn't work
I suspect what's happening is that I didn't run the createXYZ mutation as testUser, just as a generic GraphiQL user, so the owner property isn't tied to "myUserId". Is that the problem here?
How would I specify owner on my create mutations in GraphiQL?
This is the error I'm getting, pretty sure it means the XYZ object's owner is different than my testUser submitting the deleteXYZ request:
Error while executing Local DynamoDB
{
"version": "2018-05-29",
"operation": "DeleteItem",
"key": {
"id": {
"S": "18b152a6-c98d-4336-be74-1e122191"
}
},
"condition": {
"expression": "( #owner0 = :identity0) AND attribute_exists(#id)",
"expressionNames": {
"#owner0": "owner",
"#id": "id"
},
"expressionValues": {
":identity0": {
"S": "fd2a7758-f7ba-4d57-bdb0-e5346492"
}
}
}
}
Could I have to add the owner id in Amplify's GraphiQL Auth options popup?
I just ran into this issue. I was able to work around it by putting my Cognito User Sub in the username field.

Is there a way to allow a user to change it's own password on Hashicorp's Vault UI

I wanted to let users change their own password within HashiCorp's Vault (assuming, we're using userpass auth).
I don't find any way to do so. Can anyone Help?
I believe this link has your answer.
It would look something like this
path "auth/userpass/users/{{identity.entity.aliases.auth_userpass_6671d643.name}}" {
capabilities = [ "update" ]
allowed_parameters = {
"password" = []
}
}
where auth_userpass_6671d643 is the mount of your userpass authentication and can be retrieved via vault auth list command.
To make it possible to not create different policy for each user, it might be handy to use next policy:
path "auth/userpass/users/{{identity.entity.name}}" {
capabilities = [ "update" ]
allowed_parameters = {
"password" = []
}
}
It also requires admins to change entity names for each user to be equal to the username (lower-cased), but it looks more handy then another solutions.

How to create a AWS Cognito user with Terraform

I'd like to use Terraform to create AWS Cognito User Pool with one test user. Creating a user pool is quite straightforward:
resource "aws_cognito_user_pool" "users" {
name = "${var.cognito_user_pool_name}"
admin_create_user_config {
allow_admin_create_user_only = true
unused_account_validity_days = 7
}
}
However, I cannot find a resource that creates AWS Cognito user. It is doable with AWS Cli
aws cognito-idp admin-create-user --user-pool-id <value> --username <value>
Any idea on how to do it with Terraform?
In order to automate things, it can be done in terraform using a null_resource and local_exec provisioner to execute your aws cli command
e.g.
resource "aws_cognito_user_pool" "pool" {
name = "mypool"
}
resource "null_resource" "cognito_user" {
triggers = {
user_pool_id = aws_cognito_user_pool.pool.id
}
provisioner "local-exec" {
command = "aws cognito-idp admin-create-user --user-pool-id ${aws_cognito_user_pool.pool.id} --username myuser"
}
}
This isn't currently possible directly in Terraform as there isn't a resource that creates users in a user pool.
There is an open issue requesting the feature but no work has yet started on it.
As it is not possible to do that directly through Terraform in opposite to matusko solution I would recommend to use CloudFormation template.
In my opinion it is more elegant because:
it does not require additional applications installed locally
it can be managed by terraform as CF stack can be destroyed by terraform
Simple solution with template could look like below. Have in mind that I skipped not directly related files and resources like provider. Example also contains joining users with groups.
variables.tf
variable "COGITO_USERS_MAIL" {
type = string
description = "On this mail passwords for example users will be sent. It is only method I know for receiving password after automatic user creation."
}
cf_template.json
{
"Resources" : {
"userFoo": {
"Type" : "AWS::Cognito::UserPoolUser",
"Properties" : {
"UserAttributes" : [
{ "Name": "email", "Value": "${users_mail}"}
],
"Username" : "foo",
"UserPoolId" : "${user_pool_id}"
}
},
"groupFooAdmin": {
"Type" : "AWS::Cognito::UserPoolUserToGroupAttachment",
"Properties" : {
"GroupName" : "${user_pool_group_admin}",
"Username" : "foo",
"UserPoolId" : "${user_pool_id}"
},
"DependsOn" : "userFoo"
}
}
}
cognito.tf
resource "aws_cognito_user_pool" "user_pool" {
name = "cogito-user-pool-name"
}
resource "aws_cognito_user_pool_domain" "user_pool_domain" {
domain = "somedomain"
user_pool_id = aws_cognito_user_pool.user_pool.id
}
resource "aws_cognito_user_group" "admin" {
name = "admin"
user_pool_id = aws_cognito_user_pool.user_pool.id
}
user_init.tf
data "template_file" "application_bootstrap" {
template = file("${path.module}/cf_template.json")
vars = {
user_pool_id = aws_cognito_user_pool.user_pool.id
users_mail = var.COGNITO_USERS_MAIL
user_pool_group_admin = aws_cognito_user_group.admin.name
}
}
resource "aws_cloudformation_stack" "test_users" {
name = "${var.TAG_PROJECT}-test-users"
template_body = data.template_file.application_bootstrap.rendered
}
Sources
https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-cognito-userpooluser.html
https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudformation_stack
Example
Simple project based on:
Terraform,
Cognito,
Elastic Load Balancer,
Auto Scaling Group,
Spring Boot application
PostgreSQL DB.
Security check is made on ELB and Spring Boot.
This means that ELB can not pass not authorized users to application. And application can do further security check based on PostgreSQL roleswhich are mapped to Cognito roles.
Terraform Project and simple application:
https://github.com/test-aws-cognito
Docker image made out of application code:
https://hub.docker.com/r/testawscognito/simple-web-app
More information how to run it in terraform git repository's README.MD.
It should be noted that the aws_cognito_user resource is now supported in the AWS Terraform provider, as documented here: https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cognito_user
Version 4.3.0 at time of writing.

Can chrome.identity.launchWebAuthFlow be used to authenticate against Google APIs?

I'm writing a Chrome extension and have been trying to use chrome.identity.launchWebAuthFlow to authenticate with Google. I would prefer this to chrome.identity.getAuthToken (which does work) because getAuthToken gets the token for the user currently logged in to Chrome -- who may be logged in to multiple Google accounts. I want the user to be able to hook up a specific Google calendar to my extension, and that calendar might belong to a different user than they've logged in to Chrome as.
So, I've been trying to do this with chrome.identity.launchWebAuthFlow and generally failing around a mismatched redirect_uri. I've tried just about every type of credential you can set up in the Google APIs developer console. ("Chrome App" seemed like the right thing, but I have also tried Web application, Other, and iOS.) I've tried using the results of both chrome.extension.getURL('string') and chrome.app.getRedirectURL('string') as my redirect_uri.
I tried out the example app referred to by https://stackoverflow.com/questions/40384255/oauth2-angular-chrome-extension but have not been able to get that to work either.
I have a suspicion I'm trying to do something that either used to be allowed and no longer is, or just never worked.
Here's an example of my code, but I think my problem is really in the API dev console -- I don't see a way to set up a configuration that will work for an extension:
var auth_url = 'https://accounts.google.com/o/oauth2/v2/auth';
var client_key = *[client id from API dev console]*
var auth_params = {
client_id: client_key,
redirect_uri: chrome.identity.getRedirectURL("oauth2.html")
scope: 'https://www.googleapis.com/auth/calendar'
};
auth_url += '?' + $.param(auth_params);
chrome.identity.launchWebAuthFlow({url: auth_url, interactive: true}, function(token) { console.log(token); });
(I have also tried the https://accounts.google.com/o/oauth2/auth endpoint.)
Solution:
After reading the accepted answer, I wound up with this:
var auth_url = 'https://accounts.google.com/o/oauth2/auth';
var client_id = '[client ID from console]';
var redirect_url = chrome.identity.getRedirectURL("oauth2.html");
var auth_params = {
client_id: client_id,
redirect_uri: redirect_url,
response_type: 'token',
scope: 'profile'
};
auth_url += '?' + $.param(auth_params);
console.log(auth_url);
chrome.identity.launchWebAuthFlow({url: auth_url, interactive: true}, function(responseUrl) { console.log(responseUrl); });
The responseUrl is my redirect_uri with parameters -- so Google oauth returned that instead of redirecting the browser to it -- and I could go on from there.
Yes, in 2019 it still works. Finally got it working...
manifest.json
{
"name": "Extension Name",
"description": "Description",
"version": "1.0.0",
"manifest_version": 2,
"icons": {
"48": "icons/icon_48.png",
"128": "icons/icon_128.png"
},
"background": {
"scripts": [
"background.js"
],
"persistent": false
},
"oauth2": {
"client_id": "Your Client ID from Google Develpers console (Must be Web Application)",
"scopes": [
"openid", "email", "profile"
]
},
"permissions": [
"identity"
],
"key": "Your Key from Google Developer Dashboard"
}
background.js
chrome.windows.create({
'url': './content/auth/auth.html',
'width': 454,
'height': 540,
'type': 'popup'
});
auth.html
standard HTML markup that calls auth.js file
auth.js
var auth_url = 'https://accounts.google.com/o/oauth2/auth?';
var client_id = '<Client ID>'; // must be Web Application type
var redirect_url = chrome.identity.getRedirectURL(); // make sure to define Authorised redirect URIs in the Google Console such as https://<-your-extension-ID->.chromiumapp.org/
var auth_params = {
client_id: client_id,
redirect_uri: redirect_url,
response_type: 'token',
scope: 'https://mail.google.com/',
login_hint: 'real_email#gmail.com' // fake or non-existent won't work
};
const url = new URLSearchParams(Object.entries(auth_params));
url.toString();
auth_url += url;
chrome.identity.launchWebAuthFlow({url: auth_url, interactive: true}, function(responseUrl) {
console.log(responseUrl);
});
To get the Angular sample running, I needed to:
Create my own Web Application client ID in the Google developer console with an Authorized redirect URI of https://bcgajjfnjjgadphgiodlifoaclnemcbk.chromiumapp.org/oauth2
Copy that client ID into the config.json file of the sample.
The call to get redirectURI in that sample is like chrome.identity.getRedirectURL("oauth2"), the string parameter gets appended to the end of the URL based on extension ID.