Restrict access to single stream on keen - keen-io

I have read access keys on keen.io And I have a use case where I would like to use these access keys. Actually, in my system, i want to make a separate stream for every customer account and want to make sure that this stream is only accessible (could be written/read) by that specific customer only. I want to use access keys for this purpose as I think it is their one of main use cases.
Can anyone tell me how can I pass this information to an access key that it is only usable on a specific stream ONLY?

You would programmatically create an Access Key for each customer and set its permissions on creation so that it will autofill event properties with, for example, a customer id. With queries, you would set up the querying permissions with a filter so that it could only query event with that customer id.
Similar to the JSON in this example here: https://keen.io/docs/access/access-keys/#access-key-json-example
Then, any time that Access Key is used, it will only be able to query that specific data and all writes will include the autofill information that you set for that Access Key.

Related

How do I store user defined values in wit.ai?

I am new to chatbots and using the wit.ai.
I had like to store user defined values for future use, such as Name of the user.
When the user says his name. It gets stored in a variable that can be used later.
Using entities limits me to a predefined list of names.
They have changed the getting started guide. Initially they showed the way to store user queries.
What you want to use is context object. It can store information which you want to pass on for later use. It is used to save the state of conversation.
In your story, click on Bot Executes, then an action to be executed at backend and finally type the variable name like username in the update context keys with field. This will make username available for use.

Claims-based auth and circles of users

Let's think of a simple REST-based web service to store and retrieve JSON objects. Without any authentication, every user can access any data.
Now let's add usage of JWTs to authenticate users. Of course, since we are not doing authorization, still every user can access anything, but at least now we know who accesses what.
Next step: When storing an object, save the user's sub claim with the object, and verify that the user's sub claim matches the one of the requested object, and if so, deliver it. Now we have authorization on a per-user basis. So far, so easy.
Now let's add the possibility to let users share objects with other users. For the sake of simplicity, say, we want to have predefined groups (i.e., roles) and we want to let the user choose which group (role) has access to the objects they create. This is still easy, as you have a predefined list of groups, so you can let the user choose one or more, and attach them to the object. Additionally, the identity provider needs to be configured in a way that it put a groups claim into every user's token, so we can match them. As we can already see from the length of this paragraph, things become more complex.
Question 1: Am I right so far, that handling "static" groups this way it the way to go?
Now, let's give the users the opportunity to create groups on their own. This is still not complicated, but how do we make the identity provider use the dynamically created groups? For sure we do not want to make an administrator update the identity provider's configuration every day ;-).
Question 2: How do we handle dynamically created groups?
Now, finally, let's forget about groups, and let's say, that we want to allow the users to be able to simply share their objects with other users. This should be configurable for every object individually. How do we do this? Do we save a list of users on the object? If so, what exactly do we save? The sub claim? If so, how does the owner user know the appropriate values? Or ...?
And: Supposed the users want to put their friends dynamically into dynamically generated circles, how would we do that?
Question 3: How do tokens and dynamically created groups with dynamically assigned users work with each other?
In my opinion the tokens should only include identity-information(-claims) you'll need to identify the user on your ressource server or that wont change when refreshing, since you wouldn't want your user (or your app in place) to have to refresh his access tokens each and every time his permissions change (since access tokens grant access for a specific amount of time you wouldn't want your user to have access to certain ressources that he's lost the access rights to since his last token refresh by not refreshing the token and simply using the old one either). The more security related information you append to your token, the more vulnerability you may add to your system (depending on your token lifetime).
Stating so, I would (and always do) identify the users roles or groups by his user-id (which is included in the jwt-token) on the ressource server. To achieve this, I always attach the users identity-information to the current request on my ressource server and attach "dynamic"-claims like the users role or group to the identity.
By adding only the identity information I need to identify the user and the user's rights on my ressource server, I tend to use my identity providers across multiple applications without handling application scope on the identity provider, so I can use the exact same access token for multiple independent ressource servers.

How do I make private docs alongside public docs in a CouchDB database?

I'm somewhat new to CouchDB and I'm wondering how to make private docs, that is I want to have a database where all docs are public (rw, or r using a validate_doc_update) except for few/some selected docs, how would I do something like that?
And to complicate things a bit more I want them to be private to / accessible by the admin but also varying number of selected users (but no others).
I'm thinking that perhaps I could have two keys in these docs called "private" and "private_users", set them to true and [user1, user2, user3], and somehow use that info to make the docs private / only accessible by them.
So essentially it's about users being able to create docs and have them visible to everybody or just themselves and other selected users.
One way to do this would be to make the database private by setting the Security admin and members lists to the owner (making the database completely private), and then route all calls to reading documents through a backend script which checks these properties of the document through an admin account and fetches and returns the content if conditions are met, but the thing is I'd like to do this through configuring CouchDB and do CORS HTTPS calls from the clients browser directly to CouchDB, with no script in the middle.
Is this possible?
There are several potential solutions to this problem:
The problem: For a given user, allow only specific access to a given document in the database.
Database per user:
Create one database for each user and use authentication on the database for that given user. Because views do not work across databases, you will have to replicate all needed data between the different user databases to allow for a view to contain both private and public/other users' data. Because normal users can not create/delete databases, you will need to have a separate process running which watches your database for changes and creates a new user database when a new user registers.
Smart Proxy:
Create a smart proxy that wraps all documents with the user credentials and filters all results.
Document Encryption on a per User Basis:
This solution is described in a google document which was mentioned on the development mailinglist. The goal of this solution is to create a P2P like system, where you can replicate data to nodes which you don't trust.
validate_read_doc:
Have a javascript function be called on every read, in the same manner as the validate_doc_update system is applied.
For more information:
http://wiki.apache.org/couchdb/PerDocumentAuthorization
So essentially it's about users being able to create docs and have them visible to everybody or just themselves and other selected users ...... Is this possible?
Not with just couchdb...
The permissions that you set with _security in a database only apply write level security on it.
Other wise most of the documents (except the design documents) are available for every one to read. With validate functions
you can impose further restrictions on who writes the documents but again there is no way to check who is reading your documents.
rcouch has a validation on read which can help you what you want to do. Other wise if you want to go with couchdb you could use a proxy for communicating with it.

Redis newbie - equivalent approach to mysql table

I'm new to Redis and was hoping for a "best practice" solution to implementing the equivalent of a "users" table in a mysql database, for handling users in a web app.
Would I create a users SET in Redis? Or a users database with a SET for each user?
My standard setup for users is a serialized object in a standard key u:userid - this object gets retrieved on each request, and there is never any need to access only one of the properties.
You could also use a hash rather than json for the user properties, but my setup includes everything getting used as strongly typed objects and redis running on a different server from the client, so using json makes it easier to use generic deserialization and minimizes any latency issues.
In addition to the user object itself, you will need an index for any fields you need to use to find a user - for example to allow a user to log in with email address you will need a key e:email => userid. A hash will also work here - the important thing is that you need something that is O(1) to get from an email to a user object.
Sometimes parts of the user data should have their own keys - for example a followers list is a perfect match to a redis set, so is best stored in that form.
It really depends on what you'd want to do with the Users within your application. Another option would be to have each user be it's own hash, where they keys are properties (fields) for each user (firstName, lastName, etc). You could use a key that you increment as the ID generator for inserting, and potentially another set that you use to hold all of the user IDs.

Storing a Windows SID in a Database for Lookup

I have an ASP.NET MVC application where I need to allow to customers configure MembershipProviders based on their environment, but still be able to map that MembershipUser to a concrete User model in our database.
Membership.GetUser() will give me access to the logged-in user's Membership.ProviderUserKey. I can use this to relate to a User record. Our custom SQL provider will just return the User.Id, but AD is a different story. In that case, ProviderUserKey is an IdentityReference.
These lookups will happen very frequently, as you can imagine (although caching can assist in reducing the lookups at the database level).
I can't decide which route is better to go: Storing the SID as a varbinary or varchar column. This column would not be a primary key and would not have a clustered index. Knowing that I can index strings pretty well, and reading a SID in string format is certainly nicer than binary. Anyone willing to share how they solved such a situation?
Update
I don't know how I missed this SO question when I was searching before I posted, but it seems pretty clear that ActiveDirectoryMembershipProvider and ActiveDirectoryMembershipUser are not quite cut out for the task at hand, as they exist today.
An answer in that SO question linked the following article, where the following was stated:
The relative identifier portion of a
SID is unique relative to the domain,
so if the domain changes, the relative
identifier also changes.
Thus when a User object moves from one
domain to another, a new SID must be
generated for the user account and
stored in the Object-SID property.
However, each group and user has an Object-GUID, which will never change, even if the account is moved. Therefore, it would behoove me to use Object-GUID in my User class, and not Object-SID. Otherwise, someone's User record will be abandoned if they are moved and therefore breaking the relationship between their principal and the data they created.
Unfortunately, ActiveDirectoryMembershipUser doesn't let me get at Object-GUID. So, I'll either have to translate the SID to a GUID after ActiveDirectoryMembershipUser does its work, or create my own MembershipProvider that does everything I need on the spot. Unfortunately, this means I might have to duplicate effort already done for me by ActiveDirectoryMembershipProvider.
Microsoft stores SIDs as varbinary(85) in sys.server_principals
This is also a unique column, so it must have an index...
username is the LAST thing you want to index on.
SIDs only change in an AD when you change a user from one domain to another. RIDs are split into 2 groups - inbuilt (< 1000) and user RIDs. Pre-defined users such as Administrator, Guest etc always have the same RID.
If you want to handle movement of users etc, then GUID is the way to go.
username can be changed at any time in Users and Groups management.
this is different to the object name, which is invariant, but I don't believe is mandated unique across a forest. You can have any number of John Smith users.
I'd look into the ADSI objects. These are COM objects which should be accessible from ASP. MSDN explains pretty well. an ADSearch object can be used to return user attributes (e.g. including DN) from a GUID.
Sounds like you're making this a lot more difficult than it needs to be. What do you need a SID or GUID for? You already have a unique, perfectly readable identifier for the users account maintained in ActiveDirectory.
It's called "the username". Hopefully it's the same username as stored in your apps "user" table.
Your app just needs to know if that username successfully authenticated with ActiveDirectory. So if they successfully log in - you just store the fact that they are authenticated in your Session variables.
If they are configured to use the db user login, if successful set the same Session variable indicating that they successfully logged in.
No fancy GUIDs or SIDs ... simple.