I'd suggest creating a cloud code function to create the chat and within it create Chat-specific roles to which you can add users. By using a well-known format (-), you can pretty easily find and manage the role membership. In the example below, I create the Chat and admin role and add the current user (the creator of the chat) as the only member of the admin role (as well as the only one that can modify the admin role).
N.B. If you plan to create a Message class with a pointer to Chat, this won't directly prevent users from creating those objects. You'd likely need some additional cloud code (e.g. a beforeSave hook) to enforce that.
function createChat(name, public) {
var chat = new Parse.Object("Chat");
chat.set("public", public);
chat.set("name", name);
chat.save().then(function() {
var id = chat.id;
// create each role using a well-known format of <chat object id>-<role name>
var adminRole = new Parse.Role();
adminRole.setName(id+"-Admin");
adminRole.relation("users").add(Parse.User.current());
// add the current user (the creator
var adminRoleAcl = new Parse.ACL();
adminRoleAcl.setPublicWriteAccess(false);
adminRoleAcl.setPublicReadAccess(true);
adminRoleAcl.setWriteAccess(Parse.User.current(), true);
adminRole.setACL(adminRoleAcl);
var chatAcl = new Parse.ACL();
chatAcl.setPublicWriteAccess(false);
chatAcl.setPublicReadAccess(public);
chatAcl.setRoleWriteAccess(id+"-Admin", true);
chat.setACL(chatAcl);
return Parse.Object.saveAll([adminRole, chat]);
}).then(function() {
// you'd normally have response.success() here
console.log("done!");
})
}